语法
Object.defineProperty(obj, prop, descriptor)
参数
obj
- 要在其上定义属性的对象。
prop
- 要定义或修改的属性的名称。
descriptor
- 将被定义或修改的属性描述符。
返回值
被传递给函数的对象。
ES6
在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty
是定义key为Symbol的属性的方法之一。
属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。访问器描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable
- 当且仅当该属性的 configurable 为 true 时,该属性
描述符
才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。 enumerable
- 当且仅当该属性的
enumerable
为true
时,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value
- 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为
undefined
。 writable
- 当且仅当该属性的
writable
为true
时,value
才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
get
- 一个给属性提供 getter 的方法,如果没有 getter 则为
undefined
。该方法返回值被用作属性值。默认为undefined
。 set
- 一个给属性提供 setter 的方法,如果没有 setter 则为
undefined
。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined
。
记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype
,明确指定所有的选项,或者将__proto__
属性指向null
。
var o = {};
o.a = 1;
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : true,
configurable : true,
enumerable : true
});
// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : false,
configurable : false,
enumerable : false
});
function Person() { var name = null; var parents = []; Object.defineProperty(this, 'name', { get: function() { console.log('lilei!'); return name; }, set: function(value) { name = value; parents.push({ val: name }); } }); this.isName = function() { return parents; }; } var arc = new Person(); arc.name; arc.name = 'hanmeimei'; arc.name = 'Jon'; console.log(arc.isName()) // [{ val: 'hanmeimei'}, { val: 'Jon' }]