基础用法
当我们需要对对象的某个属性进行拦截或者监控时,就需要使用 Object.defineProperty 方法。该方法允许我们在对象上定义一个新属性或修改一个已经存在的属性,并指定该属性的特性(属性描述符)。
Object.defineProperty 方法接收三个参数:
obj:需要定义属性的对象。
prop:需要定义或修改的属性的名称。
descriptor:属性描述符,是一个对象,用来描述该属性的特性。
属性描述符有两种形式:数据描述符和访问器描述符。
数据描述符:用于描述一个具有值的属性,有四个可选的属性值:
value:属性的值,默认为 undefined。
writable:属性是否可写,默认为 false。
enumerable:属性是否可枚举,默认为 false。
configurable:属性是否可配置,默认为 false。
访问器描述符:用于描述一个没有值的属性,有四个可选的属性值:
get:获取属性值的方法,默认为 undefined。
set:设置属性值的方法,默认为 undefined。
enumerable:属性是否可枚举,默认为 false。
configurable:属性是否可配置,默认为 false。
下面是一个使用 Object.defineProperty 方法定义数据描述符的示例:
let obj = {};
Object.defineProperty(obj, 'age', {
value: 18,
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.age); // 18
obj.age = 20;
console.log(obj.age); // 20
上述代码中,我们使用 Object.defineProperty 方法定义了一个名为 age 的属性,并给它赋了一个初始值 18。由于 writable 属性值为 true,所以该属性可以被修改,因此我们通过给 age 赋值为 20 来更新了属性值。最后输出 obj.age 的值
关于get和set的用法
除了使用 Object.defineProperty 定义数据描述符之外,我们还可以使用它定义访问器描述符。访问器描述符不是用来描述一个具有值的属性,而是描述一个没有值的属性。
访问器描述符包含 get 和 set 两个方法,用于获取和设置属性值。下面是一个使用 Object.defineProperty 方法定义访问器描述符的示例:
let obj = {};
Object.defineProperty(obj, 'age', {
get() {
console.log('get age');
returnthis._age;
},
set(newVal) {
console.log('set age to ' + newVal);
if (newVal > 0 && newVal < 150) {
this._age = newVal;
} elseif (newVal < 0) {
this._age = 0;
} else {
this._age = 150;
}
},
enumerable: true,
configurable: true
});
obj.age = 100; // set age to 100console.log(obj.age); // get age 100
obj.age = -10; // set age to 0console.log(obj.age); // get age 0
obj.age = 200; // set age to 150console.log(obj.age); // get age 150
上述代码中,我们使用 Object.defineProperty 方法定义了一个名为 age 的属性,并指定了 get 和 set 方法。get 方法用于获取属性值,set 方法用于设置属性值,并对设置的值进行了限制,确保属性值在 0 到 150 之间。可以看到,在对 age 进行赋值操作时,会先调用 set 方法,输出 set age to ...,然后再次获取属性值时,会调用 get 方法,输出 get age 和属性值。