定义只有内部才能使用的特性,描述了属性的各种特征。是为实现JavaScript引擎用的。因此在JS中不能直接访问它们。
1.数据属性
-
[[Configurable]]
表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。(不可配置) -
[[Enumerable]]
表示能否通过for-in循环返回属性。 -
[[Writable]]
表示能否修改属性的值。 -
[[Value]]
包含这个属性的数据值。
要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty(属性所在的对象,属性的名字,描述符对象)
方法。其中描述符对象
必须是configurable、enumerable、writeable、value
。设置其中一个或多个值,可以修改对应的特性值。
var person = {
name: 'Nichole'
};
Object.defineProperty(person, "name", {
writable: false, // 设置属性不可修改
value: 'Bubble'
});
console.log(person.name); // Bubble
person.name = 'Hello';
// 非严格模式下,该操作被忽略;严格模式下,会导致抛出错误。
console.log(person.name); // Bubble
可以多次调用
Object.defineProperty()
修改同一属性,但在把configurable
特性设置为false后就会有限制了。
2.访问器属性
访问器属性不包含数据值,它包含一对getter()
和setter()
函数。在读取访问器属性时,会调用getter(),这个函数负责返回有效的值。在写入访问器属性时,会调用setter()并传入新值,这个函数负责如何处理数据。访问器属性有如下特性:
[[Configurable]]
[[Enumerable]]
-
[[Get]]
在读取属性时调用的函数,默认值为undefined -
[[Set]]
在写入属性时调用的函数,默认值为undefined
访问器属性不能直接定义,必须使用Object.defineProperty()
来定义。
var person = {
_name: 'Nichole',
count: 0
};
Object.defineProperty(person, 'name', {
get: function () {
return this._name;
},
set: function (newValue) {
this._name = newValue;
this.count += 1;
}
});
person.name = 'Bubble';
console.log(person._name) // Bubble
console.log(person.count) // 1
person对象有两个默认属性:_name
和count
。而访问器属性name
则包含一个getter()和一个setter()。
使用访问器属性的常见方式即:设置一个属性的值会导致其他属性发生变化。
- 如果只指定
getter
意味着属性不能写; - 如果只指定
setter
意味着属性不能读。
之前的浏览器不支持的使用,使用的是__defineGetter__
和__defineSetter__
。
定义多个属性:
var person = {
_name: 'Nichole',
count: 0
};
Object.defineProperties(person, {
_name: {
writable: true,
value: 'Bubble'
},
count: {
writable: true,
value: 12
},
name: {
get: function () {
return this._name;
},
set: function (newValue) {
this._name = newValue;
this.count++;
}
}
}
);
person.name = 'HAH';
console.log(person._name) // HAH
console.log(person.count) // 13
3.读取属性的特性
Object.getOwnPropertyDescriptor(person, '_name').configurable
4.扩展思考:
Vue动态数据绑定如何实现?