JavaScript 数据属性和接见器属性
一个例子
先看代码:
var obj = {name:"percy"};
console.log(obj.name); // percy
obj.name = "zyj";
console.log(obj.name); // zyj
// 这里借 Math 对象来举例
// 起首申明一下, Math 对象和上面定义的 obj 对象都只是 Object 对象的一个实例
console.log(Math.PI); // 3.1415926...
Math.PI = 1234;
console.log(Math.PI); // 3.1415926...
看到了吗?同样是 Object 的实例,obj 对象的属性却能够被改写,而 Math 对象的属性去不能被改写。好,让我们来码一行,从而让 obj 对象的属性也不能被改写:
var obj = {name:"percy"};
console.log(obj.name); // percy
Object.defineProperty(obj,"name",{writable:false});
obj.name = "zyj";
console.log(obj.name); // percy
看到了吗,这个中尚有玄机,接下来就引入了我们的主角:对象的数据属性和接见器属性。
为了示意特征是内部值,范例(ECMA-262)就把它们放到了两对儿方括号里了,比方 [[Enumerable]]。
数据属性(Data Properties)
数据属性有4个形貌其行动的特征:
[[Configurable]] : 示意可否经由过程 delete 删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为接见器属性。
[[Enumerable]] : 示意可否经由过程 for-in 轮回返回属性。
[[Writable]] : 示意可否修正属性的值。
[[Value]] : 包括这个属性的数据值。读取属性值的时刻,从这个位置读;写入属性值时,把新值保留在这个位置。默许值是 undefined。
像如许(
var obj = new Object(); obj.name = "percy";
)或许像经由过程对象字面量(var obj = {name: "percy"};
)直接在对象上定义的属性,它们的 [[Configurable]]、[[Enumerable]] 和 [[Writable]] 特征默许都被设置为 true,而 [[Value]] 特征被设置为指定的值。
这里注重一下这个(能够先跳过,完了再看):
var person = {}; // 新建一个空对象
Object.defineProperty(person,"name",{
value: "percy"
});
console.log(Object.getOwnPropertyDescriptor(person,"name"));
// 打印:Object {value: "percy", writable: false, enumerable: false, configurable: false}
没有按上面的2种要领为对象增加属性,而直接经由过程 Object.defineProperty()
为对象增加属性以及值,这类情况下,这个对象的这个属性的别的3个特征的默许值都是 false。
要修正属性默许的特征,必须运用 ECMAScript 的 Object.defineProperty() 要领。
Object.defineProperty( obj, prop, descriptor)
obj:须要定义属性的对象。
prop:需定义或修正的属性的名字。
descriptor:一个包括设置特征的对象
var person = {name: "percy"};
Object.defineProperty(person,"name",{
writable: false
});
console.log(person.name); // percy
person.name = "zyj";
console.log(person.name); // percy
for(let prop in person){
console.log(prop + " : " + person[prop]);
} // name : percy
Object.defineProperty(person,"name",{
enumerable: false
});
for(let prop in person){
console.log(prop + " : " + person[prop]);
} // 什么也没打印
Object.defineProperty(person,"name",{
configurable: false
});
Object.defineProperty(person,"name",{
configurable: true
}); // 报错:TypeError: Cannot redefine property: name(…)
// 一旦把属性定义为不可设置的,那末就不再能把属性定义回可设置的了。
接见器属性(Accessor Properties)
接见器属性不包括数据值,它们包括一对儿 getter
和 setter
函数(不过,这两个函数都不是必须的)。在读取接见器属性时,会挪用 getter 函数,在写入接见器属性时,又会挪用 setter 函数并传入新值。
接见器属性有以下4个特征:
[[Configurable]]:示意可否经由过程 delete 删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为数据属性。
[[Enumerable]]:示意可否经由过程 for-in 轮回返回属性。
[[Get]]:在读取属性时挪用的函数。默许值为 undefined。
[[Set]]:在写入属性时挪用的函数。默许值为 undefined。
接见器属性不能直接定义,必须运用 Object.defineProperty()
来定义。
var book = {
_year : 2004,
edition : 1
};
Object.defineProperty(book,"year",{
get : function () {
alert(this._year);
},
set : function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year; // 弹出窗口,显现 2004
book.year = 2005;
console.log(book.edition); // 2
如果上面的代码有不晓得处所,参看这里,JavaScript明白对象:属性范例(引荐)
定义多个属性
var obj = {};
Object.defineProperties(obj, {
"property1": {
value: true,
writable: true
},
"property2": {
value: "Hello",
writable: false
}
// 等等.
});
console.log(obj); // Object {property1: true, property2: "Hello"}
读取属性的特征
Object.getOwnPropertyDescriptor(obj, prop) 返回指定对象上一个自有属性对应的属性形貌符。(自有属性指的是直接给予该对象的属性,不须要从原型链上举行查找的属性)
var girl = {name: "zyj"};
console.log(Object.getOwnPropertyDescriptor(girl,"name"));
// Object {value: "zyj", writable: true, enumerable: true, configurable: true}
Object.defineProperties(girl,{
name:{
writable: false
},
age:{
writable: true,
value: 22
}
});
console.log(Object.getOwnPropertyDescriptor(girl,"name"));
// Object {value: "zyj", writable: false, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(girl,"age"));
// Object {value: 22, writable: true, enumerable: false, configurable: false}
var descriptor = Object.getOwnPropertyDescriptor(girl,"age");
console.log(descriptor.value); // 22
console.log(descriptor.configurable); // false
console.log(descriptor.writable); // true
console.log(descriptor.get); // undefined
console.log(descriptor.set); // undefined
摘抄自文末的链接
A property is a name (string identifier) associated with a property descriptor.
As of ECMAScript 5, three property types are available:
Internal Properties
Data properties
Accessor properties
参考资料
【书】《JavaScript 高等程序设计(第三版)》