Object.defineProperty个人理解

105 阅读1分钟

基础语法:

let obj = {}
Object.defineProperty(obj, 'keyOne', {
     //四个属性: 
	enumerable: false, //对象的属性是否能被for inObject.keys()枚举,如果使用defineProperty默认为false,字面量定义 let o = {a: 11},那么a是可枚举的,即enumerable默认是true
	configurable: false, //使用defineProperty时定义的属性是否可以被删除,以及除value和writable特性外的其他特性是否能被修改, 默认值为false,
	writable:  false, //默认false,若为false则为只读 不可修改
	value: undefined, //默认undefined,
	//两个方法
	get(){
		return obj['keyOne']
	},
	set(val){
		obj['keyOne'] = val
	}
    //注意:getter/setter不能与value/writable 共存, 即如果设置了value则不能设置set或者get方法, 如果设置了writable也不能设置set或者get方法, 否则会抛出异常
  }
)

关于enumerable的讲解例子: 原文 developer.mozilla.org/zh-CN/docs/…

var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable: true });
Object.defineProperty(o, "b", { value : 2, enumerable: false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable 默认为 false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
Object.defineProperty(o, Symbol.for('e'), {
  value: 5,
  enumerable: true
});
Object.defineProperty(o, Symbol.for('f'), {
  value: 6,
  enumerable: false
});

for (var i in o) {
  console.log(i);
}
// logs 'a' and 'd' (in undefined order)

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false
o.propertyIsEnumerable('d'); // true
o.propertyIsEnumerable(Symbol.for('e')); // true
o.propertyIsEnumerable(Symbol.for('f')); // false

var p = { ...o }
p.a // 1
p.b // undefined
p.c // undefined
p.d // 4
p[Symbol.for('e')] // 5
p[Symbol.for('f')] // undefined

关于configurable的讲解例子: 原文:developer.mozilla.org/zh-CN/docs/…

var o = {};
Object.defineProperty(o, 'a', {
  get() { return 1; },
  configurable: false
});

Object.defineProperty(o, 'a', {
  configurable: true
}); // throws a TypeError
Object.defineProperty(o, 'a', {
  enumerable: true
}); // throws a TypeError
Object.defineProperty(o, 'a', {
  set() {}
}); // throws a TypeError (set was undefined previously)
Object.defineProperty(o, 'a', {
  get() { return 1; }
}); // throws a TypeError
// (even though the new get does exactly the same thing)
Object.defineProperty(o, 'a', {
  value: 12
}); // throws a TypeError // ('value' can be changed when 'configurable' is false but not in this case due to 'get' accessor)

console.log(o.a); // logs 1
delete o.a; // Nothing happens
console.log(o.a); // logs 1