美文网首页
JS创建对象方案(一)

JS创建对象方案(一)

作者: 未路过 | 来源:发表于2022-09-03 14:29 被阅读0次

5.1 JavaScript的面向对象

JavaScript其实支持多种编程范式的,包括函数式编程和面向对象编程

  1. JavaScript中的对象被设计成一组属性的无序集合,像是一个哈希表,有key和value组成;
  2. key是一个标识符名称,value可以是任意类型,也可以是其他对象或者函数类型;
  3. 如果值是一个函数,那么我们可以称之为是对象的方法;

如何创建一个对象呢?

  1. 早期使用创建对象的方式最多的是使用Object类,并且使用new关键字来创建一个对象:
  2. 这是因为早期很多JavaScript开发者是从Java过来的,它们也更习惯于Java中通过new的方式创建一个对象;
  3. 后来很多开发者为了方便起见,都是直接通过字面量的形式来创建对象: 这种形式看起来更加的简洁,并且对象和属性之间的内聚性也更强,所以这种方式后来就流行了起来;

5.2 创建对象的两种方式

41.png

5.3 对对象属性进行操作

43.PNG
var obj = {
  name: "why",
  age: 18
}

// 获取属性
console.log(obj.name)

// 给属性赋值
obj.name = "kobe"
console.log(obj.name)

// 删除属性
// delete obj.name
// console.log(obj)

// 需求: 对属性进行操作时, 进行一些限制
// 限制: 不允许某一个属性被赋值/不允许某个属性被删除/不允许某些属性在遍历时被遍历出来

// 遍历属性
for (var key in obj) {
  console.log(key)
}

5.4 Object.defineProperty

42.png

var obj = {
  name: "why",
  age: 18
}

// 属性描述符是一个对象
Object.defineProperty(obj, "height", {
  // 很多的配置
  value: 1.88
})

console.log(obj)
console.log(obj.height)

1.属性描述符

属性描述符的类型有两种:

  1. 数据属性(Data Properties)描述符(Descriptor);
  2. 存取属性(Accessor访问器 Properties)描述符(Descriptor);
44.PNG

2.数据属性描述符

45.PNG
  1. configurable
    const obj = {
        name:"why",
        age:18,
        friends:{
          name:"kobe"
        },
        hobbies:["篮球","足球"]
      }


 //Object.defineProperty()//
      /* 直接在对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象 */
      
      let res = Object.defineProperty(obj, "name", {
        value:"new setting value",
       //第一种:当我们直接在一个对象上定义某个属性的时候,这个属性的configurable为true
       //第二种:当我们通过属性表舒服定义一个属性的时候,这个属性的configurable默认为false
       //configurable:false
        
      })

    //  delete obj.name
      
      console.log(obj)
      //{age: 18, friends: {…}, hobbies: Array(2)} 
      //不写/configurable:false的话,name能删除是因为这个obj是属于第一种,configurable的默认值是true
      //如果在里面设置configurable为flase之后,就不能删除了
      ////设置了configuratble为false之后,就不能删除address和改变它的definProperty里面的configurable属性。

      console.log(res === obj)//true


       Object.defineProperty(obj, "name", {
        value:"new setting value2",
       //第一种:当我们直接在一个对象上定义某个属性的时候,这个属性的configurable为true
       //第二种:当我们通过属性表舒服定义一个属性的时候,这个属性的configurable默认为false
       configurable:true//如果上一个definProerty的时候设置了configurableweifalse,第二次就不能再次把他它变成了false
        
      })

2.enumrable
第一种:当我们直接在一个对象上定义某个属性时,这个属性的[[Enumerable]]为true;
第二种:当我们通过属性描述符定义一个属性时,这个属性的[[Enumerable]]默认为false;

      const obj = {
        name:"why",
        age:18,
        friends:{
          name:"kobe"
        },
        hobbies:["篮球","足球"]
      }

 

     console.log(Object.keys(obj));//返回一个数组,里面是对象里面的所有可以遍历的属性的key名字
     //(3) ['age', 'friends', 'hobbies']
      Object.keys(obj).map((currentValue,index, arr) => {
        console.log(obj[currentValue])
      })

     //Enumerable:表示属性是否可以通过for-in或者Object.keys()返回该属性
     for(let key in obj) {
      console.log(key, obj[key])
     }
     /* 
     name why
    test.html:31 age 18
    test.html:31 friends {name: 'kobe'}
    test.html:31 hobbies (2) ['篮球', '足球']
     */

      var obj = {
  name: "why",
  age: 18
}

//数据属性描述符
Object.defineProperty(obj, "address", {
  value:"北京市",// 默认值undefined
  configuratble:false,// 默认值false
  //该特殊是配置对应的属性(address)是否是可以枚举
  enumerable:false,//默认值false
})
console.log(obj)//{name: 'why', age: 18, address: '北京市'}
for (var key in obj) {
  console.log(key)//name //age//address
}
console.log(Object.keys(obj))//) ['name', 'age', 'address']


//设置enumerable为false的时候,是不可被枚举,输出为下

//{name: 'why', age: 18, address: '北京市'}
//name age 
//['name', 'age']

3.writable
[[Writable]]:表示是否可以修改属性的值;
p 当我们直接在一个对象上定义某个属性时,这个属性的[[Writable]]为true;
p 当我们通过属性描述符定义一个属性时,这个属性的[[Writable]]默认为false;

const obj = {
  name:"my",
  age:18,
  address:"none"
}
//数据属性描述符
Object.defineProperty(obj, "address", {
  value:"北京市",// 默认值undefined
  configuratble:false,// 默认值false
  //该特殊是配置对应的属性(address)是否是可以枚举
  enumerable:true,//默认值false
  //该特性是属性是否是可以赋值(写入值) 
  writable: true// 默认值false

})
//当设置为writable为false的时候
obj.address = "上海市"
console.log(obj.address)//"北京市"
//当设置为ture的时候
//上海市

4.value
n [[value]]:属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改;
p 默认情况下这个值是undefined;

3.存取属性描述符

46.PNG
 var obj = {
  name: "why",
  _address: "北京市"
}
/*,1.,第一个场景的话就是我们隐藏某一个私有属性,不希望直接被外界使用和赋值

我不希望address这个属性随随便便被暴露出去,我们比如说给他来了一个下划线,

因为一般下划线开头的话,我们会表示他是一个私有的,然后呢使用了address这个属性名字,
来获取或者设置_address, 这个样子的化我们就不知道这个对象还有_address这个属性名

2.如果我们希望截获某一个属性它访问和设置值的过程时, 也会使用存储属性描述符

*/
 
 Object.defineProperty(obj, "address", {
  enumerable: true,
  configurable: true,
  get: function() {
    foo()
    return this._address //这个this值得是obj,因为是obj.address调用
  },
  set: function(value) {
    bar()
    this._address = value
  }
})

console.log(obj.address)

obj.address = "上海市"
console.log(obj.address)

function foo() {
  console.log("获取了一次address的值")
}

function bar() {
  console.log("设置了addres的值")
}
      
console.log(obj)

/* 

获取了一次address的值
北京市
设置了addres的值
获取了一次address的值
上海市

{name: 'why', _address: '上海市'}
address
: 
(...)
name
: 
"why"
_address
: 
"上海市"
*/

5.5 同时定义多个属性

image.png
var obj = {
  // 私有属性(js里面是没有严格意义的私有属性) 就是别人不知道这个属性的名字,不能访问这个属性
  /* 在整个JS社区里面,一般情况下,我们以下划线开头的某一个属性,
  我们就认为我们就认为他是一个私有属性 */
  _age: 18,
  _eating: function() {},
}

Object.defineProperties(obj, {
  name: {
    configurable: true,
    enumerable: true,
    writable: true,
    value: "why"
  },
   age: {
    configurable: true,
    enumerable: false,
    get: function() {
      return this._age
    },
    set: function(value) {
      this._age = value
    }
  } 
})

obj.age = 19
console.log(obj.age)

console.log(obj)

如果设置age的enumerable为false,打印obj的话


image.png

如果设置address的enumerable为true,打印obj的话


image.png
可以发现age一个是虚的一个是实的。代表能不能列举。

另外,在js中还有另一种写法

/* var obj = {
  _age: 18,
  _eating: function() {},
}
 */

 var obj = {
 
  _age: 18,
  _eating: function() {},
  set age(value) {
    this._age = value
  },
  get age() {
    return this._age
  } 
}

/* ,在我们开发里面,如果我们想要给我们的某一个某一个对象的某一个属性,给它定义对应的get和set,
而且另外它的这个值和这个值,我们想要使用默认的时候,其实我们这里可以这样来做 

如果age的configurable为true,enumerable为true,那我们可以把definproperties里面的age这个代码给注释掉,
可以在obj里面直接定义set和get
例如obj.age = 19, console.log(obj.age)

*/

obj.age = 19
console.log(obj.age)
console.log(obj)


/* 
在obj里面直接写set和get何用definProperty有一些差异,就是直接在obj中写就是直接设置了enumerable的值为true和configurable为true。
,这个时候和definProperty中的enumerble为true和configurable为true的结果一样。只不过如果我们用definProperty来写的话,你可以更加精准的去控制我们这个属性。
*/



Object.defineProperties(obj, {
  name: {
    configurable: true,
    enumerable: true,
    writable: true,
    value: "why"
  },
/*   age: {
    configurable: true,
    enumerable: true,
    get: function() {
      return this._age
    },
    set: function(value) {
      this._age = value
    }
  } */
})

5.6 获取属性描述符Object.getOwnPropertyDescriptor

image.png
var obj = {
  _age: 18,
  _eating: function() {}
}

Object.defineProperties(obj, {
  name: {
    configurable: true,
    enumerable: true,
    writable: true,
    value: "why"
  },
  age: {
    configurable: true,
    enumerable: true,
    get: function() {
      return this._age
    },
    set: function(value) {
      this._age = value
    }
  }
})

// 获取某一个特性属性的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj, "name"))
//{value: 'why', writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj, "age"))
//{enumerable: true, configurable: true, get: ƒ, set: ƒ}

// 获取对象的所有属性描述符
console.log(Object.getOwnPropertyDescriptors(obj))
image.png
     var obj = {
        name: "why",
        age: 18,
      };

      // 1.禁止对象继续添加新的属性
      Object.preventExtensions(obj);

      obj.height = 1.88;
      obj.address = "广州市";

      console.log(obj); //{name: 'why', age: 18}

      // 2.禁止对象配置/删除里面的属性
      // for (var key in obj) {
      //   Object.defineProperty(obj, key, {
      //     configurable: false,
      //     enumerable: true,
      //     writable: true,
      //     value: obj[key]
      //   })
      // }


      /* 
      可以不用像上面那么写,因为js给我们提供了方法
      密封对象,不允许配置,不可配置就是不可以删除属性:seal
      实际是调用preventExtensions
      并且将现有属性的configurable:false
      */
      Object.seal(obj);

      delete obj.name;
      console.log(obj.name);//why

      // 3.让属性不可以修改(writable: false)
      Object.freeze(obj);

      obj.name = "kobe";
      console.log(obj.name);//why

相关文章

  • JS创建对象方案(一)

    5.1 JavaScript的面向对象 JavaScript其实支持多种编程范式的,包括函数式编程和面向对象编程:...

  • JS创建对象方案(二)

    6.1 创建对象方案-字面量 这种方式有一个很大的弊端:创建同样的对象时,需要编写重复的代码; 6.2 创建对象方...

  • JS对象

    JS 创建对象 批量创建对象

  • 6.JavaScript中

    JS对象创建: JS通过构造函数创建对象: JS内置对象window: 所有的全局变量都是window的属性 所有...

  • JS笔记-006-JS对象-数字-字符串-日期-数组-逻辑

    JS对象 创建 JavaScript 对象 通过 JavaScript,您能够定义并创建自己的对象。 创建新对象有...

  • JS对象

    1、JS中的对象(Object) 1.1、创建空白对象 1.2、构造函数(就是为了创建对象实例) 一、可以创建对象...

  • 面向对象案例:随机方块

    1.创建画布 2.创建工具对象--tools.js 3.创建box盒子对象--box.js 3.1创建构造函数 3...

  • js的类和对象的创建与技术

    js的类和对象的创建的技术 一:类和对象的调用 Js代码 二:函数创建对象 this指当前类的属性与java相似(...

  • JS创建对象

    一、基本方法 1.字面量:var o = {}; 2.构造函数:var o = new Object(); 二...

  • JS创建对象

    工厂模式 由于在ECMAScript无法创建类,所以用函数的封装以特定接口创建对象 问题:解决了创建多个相似对象的...

网友评论

      本文标题:JS创建对象方案(一)

      本文链接:https://www.haomeiwen.com/subject/rxsunrtx.html