1.属性描述符
var myObject = {
a: 2,
};
Object.getOwnPropertyDesciptor(myObject,"a",{
value: 2, // 值
writable: true, // 是否可以修改属性的值
configurable: true, // 是否可以配置
enumerable: true // 可枚举
});- configurable
confifurable: true 可以使用defineProperty()方法来修改属性描述符。configurable: false 不可配置,是单向操作,无法撤销,同时会禁止删除这个属性。
但有一个小例外:属性设置为configurable: false,我们可以把writable的状态由true改为false,但无法由false改为true。
var myObject = {
a: 2
};
myObject.a // 2
delete myObject.a;
myObject.a // undefined
Object.defineProperty(myObject, "a", {
value: 2,
writable: true,
configurable: false,
enumberable: true
});
myObject.a // 2
delete myObject.a;
myObject.a // 2 删除失败- enumerable
var myObject = {};
Object.defineProperty(myObject,"a",{
value: 2,
enumerable: true, // 让a像普通属性一样可以枚举
});
Object.defineProperty(myObject,"b",{
value: 3,
enumerable: false, // 让b不可枚举
});
("b" in myObject); // true
myObject.hasOwnProperty("b"); // true
for(var k in myObject) {
console.log(k,myObject[k]);
}
// a 2in和hasOwnProperty()区别在于是否查找[[prototype]]链。
还有别的方式区分是否可枚举:
var myObject = {};
Object.defineProperty(myObject,"a",{
value: 2,
enumerable: true,
});
Object.defineProperty(myObject, "b",{
value: 3,
enumerable: false,
});
myObject.propertyIsEnumerable("a"); // true
myObject.propertyIsEnumerable("b"); // false
Object.keys(myObject); // ["a"]
Object.getOwnPropertyNames(myObject); // ["a","b"]
propertyIsEnumerable 检查给定的属性名是否直接存在于对象中(而不是原型链上)并且满足enumerable: true。
Object.keys() 返回一个数组,包含所有可枚举属性。Object.getOwnPropertyNames() 返回一个数组,包含所有属性,无论是否可枚举。
2.不变性
- 对象常量
var myObject = {};
Object.defineProperty(myObject, "FAVORITE_NUMBER",{
value: 4,
writeable: false,
configurable: false,
});- 禁止扩展(
Object.preventExtensions())
var myObject = {
a: 2
};
Object.preventExtensions(myObject);
myObject.b = 3;
myObject.b; // undefined- 密封(
Object.seal())
这个方法实际上会在一个现有对象上调用Object.preventExtensions()并把所有现有属性标记为configurable: false。
- 冻结
这个方法实际上会在一个现有对象上调用Object.freeze()并把所有数据访问属性标记为writable: false。
3.Getter和Setter 访问描述符
var myObject = {
// 给a定义一个getter
get a() {
return this._a_;
},
// 给a定义一个setter
set a(val) {
this._a_ = val * 2,
},
};
myObject.a = 2; // 设置属性值时调用setter
myObject.a; // 4 获取属性值时调用getter4.存在性
var myObject = {
a: 2
};
("a" in myObject); // true
("b" in myObject); // false
myObject.hasOwnProperty("a"); // true
myObject.hasOwnProperty("b"); // falsein操作符会检查属性是否在对象及其[[Prototype]]原型链中。
hasOwnProperty()会检查属性是否在myObject对象中,不会检查[[Prototype]]链。
所有的普通对象都可以通过对于Object.prototype的委托来访问hasOwnProperty()。但是Object.create(null)不会连接Object.prototype(),所以在这种情况下就会失败。