对象属性描述符
- 可写(writable attribute),表明是否可以设置该属性的值
- 可枚举(enumerable attribute),表明是否可以通过for/in循环返回该值
- 可配置(configurable attribute),表明是否可以删除或修改该属性
在es5之前,通过代码给对象创建的所有属性都是可写的、可枚举的和可配置的。在es5中则可以对这些特性加以配置
writable
示例代码:
var one = {}
Object.defineProperty(one, "a", {
value : 1,
writable : false,
configurable: true,
enumerable: true
})
one.a = 2;
console.log(one.a) //1
如示例,当将对象的属性的writable特性定义为false时,对属性值的修改就会静默失败
configurable
只要属性是可配置的,就可以使用defineProperty()方法来修改属性:
var one = {}
Object.defineProperty(one, "a", {
value : 1,
writable : true,
configurable: false,
enumerable: true
})
console.log(one.a) //1
one.a = 2;
console.log(one.a) //2
delete one.a
console.log(one.a) //2
Object.defineProperty(one, "a", {
value: 3,
writable: true,
configurable: true,
enumerable: true
}) //TypeError
当属性的configurable特性设置为false时,此属性无法使用delete删除,操作会默认失败,因为此属性是不可配置的,同时无法再修改configurable特性,会产生一个TypeError,即configurable修改成false是单向操作
enumerable
此描述符控制的是属性是否会出现在对象的属性枚举中,比如说for..in循环。如果把enumerable设置成false,这个属性就不会出现在枚举中,虽然可以正常访问。
var one = {b:2}
Object.defineProperty(one, "a", {
value : 1,
writable : true,
configurable: true,
enumerable: false
})
for (var key in one) {
console.log(key + '---' + one[key]) //b---2
}
如上例所示,one对象定义了一个不可枚举的属性a,那么在for..in循环遍历时就无法获取到a属性,当你不希望某些特殊属性出现在枚举中,那就把它设置成enumerable:false
Getter和Setter
在es5中可以使用getter和setter部分改写默认操作,但是只能应用在当个属性上,无法应用在整个对象上。getter是一个隐藏函数,会在获取属性值时调用。setter也是一个隐藏函数,会在设置属性值时调用
var one = {
get a() {
return this._a_;
},
set a(val) {
this._a_ = val * 2
}
}
one.a = 2
console.log(one.a) //4
Tips:当只对属性定义getter而没有定义setter时,此属性进行复制操作时将被忽略,赋值会失败但是不会报错
检测属性
js对象可以看作是属性的集合,因此我们会经常检测集合中成员的所属关系,即判断某个属性是否存在于某个对象中。可以通过in运算符、hasOwnProperty()和propertyIsEnumerable()方法来检测
in和hasOwnProperty
in运算符左侧是属性名,右侧是对象,如果对象的自由属性或继承属性中包含这个属性则返回true,对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性。对于继承属性将返回false:
var one = {
a:1
}
console.log('a' in one) //true
console.log('b' in one) //false
console.log('toString' in one) //true
console.log(one.hasOwnProperty('a')) //true
console.log(one.hasOwnProperty('b')) //false
console.log(one.hasOwnProperty('toString')) //false
propertyIsEnumerable
propertyIsEnumerable()会检查给定的属性是否直接存在于对象中并且满足enumerable:true:
var one = {}
Object.defineProperty(one, "a", {
value : 1,
enumerable: true
})
Object.defineProperty(one, "b", {
value : 2,
enumerable: false
})
console.log(one.propertyIsEnumerable('a')) //true
console.log(one.propertyIsEnumerable('b')) //false
console.log(Object.keys(one)) //['a']
console.log(Object.getOwnPropertyNames(one)) //['a','b']
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。