乐趣区

关于前端:对ObjectdefineProperty的一点探讨

引子

最近读高程 4 的时候,发现外面有一句话“一个属性被定义为不可配置之后,就不能再变回可配置的了。再次调用 Object.defineProperty() 并批改任何非 writable 属性会导致谬误”,亲自实际之后,发现这句话的后半段说得有点问题。

当 writable 为 true 时,批改 value 属性不会导致谬误
let person = {};
Object.defineProperty(person, "name", {
 configurable: false,
 writable: true,
 value: "Nicholas"
});

Object.defineProperty(person, "name", {value: "Twittytop"}); 
当 writable 为 true 时将它批改为 false 不会导致谬误(enumerable 属性不行)
let person = {};
Object.defineProperty(person, "name", {
 configurable: false,
 writable: true
});

Object.defineProperty(person, "name", {writable: false}); 
当 writable 为 false 时将它批改为 true 也会导致谬误
let person = {};
Object.defineProperty(person, "name", {
 configurable: false,
 value: "Nicholas"
});

Object.defineProperty(person, "name", {writable: true}); 

对于 writable

当 writable 为 false 时,value 值如果是一个数组或对象,批改外面的值将不会报错

let person = {};
Object.defineProperty(person, "friend", {
 configurable: false,
 writable: false,
 value: ["Twittytop", "Nicholas"]
});
person.friend.push("Matt"); 

或者

let person = {};
Object.defineProperty(person, "friend", {
 configurable: false,
 writable: false,
 value: {name: "Twittytop"}
});
person.friend.name = "Nicholas"; 

get 和 Object.defineProperty

过后用 get 关键字时,它和通过 Object.defineProperty 定义的 get 属性有一些轻微的差异。

在 class 中,当应用 get 关键字时,属性将被定义在实例的原型上,而应用 Object.defineProperty 时,属性将被定义在实例上。

class Person {get name () {return 'Twittytop';}
}
var p = new Person();
console.log(p.hasOwnProperty('name')); // false
console.log(Object.getPrototypeOf(p).hasOwnProperty('name')); // true

Object.defineProperty(p, 'job', {value: 'engineer'});
console.log(p.hasOwnProperty('job')); // true 
退出移动版