从ES5开始,对象的每一个属性都具备了属性描述符。
对u象的属性描述符是真的常见,这里就简要概括一下吧。对象的属性描述符有:
- [[value]]
- [[writable]]
- [[configurable]]:配置属性描述符可否再次被修改以及是否可delete该属性
- [[enumerable]]
- [[get]]
- [[set]]
与属性描述符常用相关的方法有:
- Object.defineProperty(obj::object,key::string, propertyObj::object)
- Object.getOwnPropertyDescriptor(obj::object, key::string)
- Object.freeze(obj::object)
下面可以举例子讨论一下:
var obj = {"num1": 1, "num2": 2}
Object.freeze(obj)//对象已经被冻结,所以该对象的所有属性均变得是常量,configurable为false,enumerable为true
obj.num1 = "one"//非严格模式不具有作用,严格模式下报错
console.log(Object.getOwnPropertyDescriptor(obj, "num1"))
//{"value":1,"writable":false,"configurable":false,"enumerable":true}
再举一个例子:
var obj = {"num1": 1, "num2": 2}
Object.defineProperty(obj, "num1", {
"value": 2,
"writable": false,
"configurable": false,
"enumerable": true
})
obj.num1 = "one"//do not work
2.关于属性描述符中的访问器属性[[get]]和[[set]]
这样认为,访问器属性[[get]]和[[set]]就像是给对象的属性取别名一样,毕竟如果不是别名的话,那岂不是会造成无限循环?还有一个要注意的地方就是,如果只设置了get的话,那么该别名属性的值不能够被更改,尝试写将不会有任何效果;如果只设置set的话,那么在非严格模式下读会返回undefined。下面举几个例子:
var obj = {"_name": "yow"}
Object.defineProperty(obj, "name", {
"get": function(){return this._name;}
})
console.log(obj.name)//"yow"
obj.name = "ahaha"
console.log(obj.name)//"yow"
再看一个只设置set的例子:
var obj = {"_name": "yow"}
Object.defineProperty(obj, "name", {
"set": function(newName){this._name = newName}
})
obj.name = "ahaha"
console.log(obj.name)//undefined
console.log(obj._name)//"ahaha"
END