在使用js的Object.defineProperty来给一个对象定义属性时,为什么没有设置writable,configurable,enumerable为false,却改变不了它的value和读出它的属性名?
首先,我们了解一下Object.defineProperty的四个数据属性
configurable: 仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false
enumerable :仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false
writable: 仅当仅当该属性的writable为 true 时,该属性才能被赋值运算符改变。默认为 false
value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
接着,我们来看一下代码。
var person={};
Object.defineProperty(person,"name",{
value:'Margot'
});
console.log(person.name); //Margot
person.name='Alice';
console.log(person.name); //Margot
console.log(Object.keys(person)); // []
这是因为,在调用Object.defineProperty()方法创建一个新的属性时,如果不指定,writable,configurable,enumerable三个特性的默认值都为false,所以我们无法对它的属性进行更改、写入和循环返回出属性名。
另外,我们要知道,在非严格模式下,person.name='Alice';
这行赋值会被忽略;在严格模式下,会导致抛出错误。
但如果我们用var定义person的时候就给了一个name属性,也就是说调用Object.defineProperty()方法只是修改已定义的属性的特性时,就可以正常更改、写入和循环返回了。如下所示
var person={
name:'Mike'
};
Object.defineProperty(person,"name",{
value:'Margot'
});
console.log(person.name); //Margot
person.name='Alice';
console.log(person.name); //Alice
console.log(Object.keys(person)); // [ 'name' ]