在 JavaScript 中,给对象增加一个属性是非常简单的,直接调用属性并赋值即可。
const obj = {
};
obj.name = 'Tom';
console.log(obj);
/**
* 输出:
* {name: 'Tom'}
*/
通过这种方式添加的属性,可以随意操作:
可修改:
// 可修改
+ obj.name = 'Jim';
+ console.log(obj.name);
/**
* 输出:
* 'Jim'
*/
可枚举:
// 可枚举
+ for (let key in obj) {
+ console.log(`${key} : ${obj[key]}`);
+ }
/**
* 输出:
* name : Jim
*/
可删除:
// 可删除
+ delete obj.name;
+ console.log(obj);
/**
* 输出:
* {}
*/
如果想通过 Object.defineProperty
实现上面的功能,可以使用下面的代码:
- obj.name = 'Tom';
+ Object.defineProperty(obj, 'name', {
+ value: 'Tom',
+ writable: true,
+ enumerable: true,
+ configurable: true,
+ });
在对 Object.defineProperty
深入学习之前,先对这个方法签名有一个认识:
Object.defineProperty(obj, prop, descriptor);
从函数签名中可以看出,defineProperty
是 Object
上的一个静态方法,可以传递三个参数:
obj
要定义属性的对象prop
要定义或修改的属性名称descriptor
要定义或修改属性的描述符返回值是被传递给函数的对象,也就是第一个参数 obj
。
描述符可以有以下几个可选值:
configurable
enumerable
value
writable
get
set
通过 Object.defineProperty
来为对象定义一个属性。
const obj = {
};
Object.defineProperty(obj, 'name', {
});
console.log(obj);
/**
* 输出:
* {name: undefined}
*/
从输出的结果可以看出,在对象 obj
上增加一个属性 name
,但是它的值是 undefined
。
如果想给属性赋值,可以使用描述符中的 value
属性。
- Object.defineProperty(obj, 'name', {});
+ Object.defineProperty(obj, 'name', {
+ value: 'Tom',
+ });
/**
* 输出:
* {name: 'Tom'}
*/
一般情况下,修改一个对象中的属性值,可以使用 obj.name = 'Jim'
的形式。
+ obj.name = 'Jim';
+ console.log(obj);
/**
* 输出:
* {name: 'Tom'}
*/
从输出结果可以看出,并没有修改成功。如果想修改属性值,可以把描述符中的 writable
设置为 true
。
Object.defineProperty(obj, 'name', {
value: 'Tom',
+ writable: true,
});
枚举对象的属性,可以使用 for...in
。
+ for (let key in obj) {
+ console.log(`${key} : ${obj[key]}`);
+ }
比较奇怪的是,执行上面的代码没有输出任何信息。
如果想正常枚举对象的属性,可以将描述符中的 enumerable
值设置为 true
。
Object.defineProperty(obj, 'name', {
value: 'Tom',
writable: true,
+ enumerable: true,
});
当这个属性不需要时,可以通过 delete
来删除。
+ delete obj.name;
+ console.log(obj);
/**
* 输出:
* {name: 'Jim'}
*/
从输出结果可以看出,并没有达到预期的效果。如果想从对象上正常删除属性,可以将描述符中的 configurable
设置为 true
。
Object.defineProperty(obj, 'name', {
value: 'Tom',
writable: true,
enumerable: true,
+ configurable: true,
});
如果需要获取对象的值,可以使用描述符中的 get
。
const obj = {
};
let _tmpName = 'Tom';
Object.defineProperty(obj, 'name', {
get() {
return _tmpName;
},
});
console.log(obj.name);
/**
* 输出:
* {name: 'Tom'}
*/
如果需要设置对象的值,可以使用描述符中的 set
,它需要传递一个参数,就是修改后的值。
Object.defineProperty(obj, 'name', {
get() {
return _tmpName;
},
+ set(newVal) {
+ _tmpName = newVal;
+ },
});
+ obj.name = 'Jim';
+ console.log(obj.name);
/**
* 输出:
* {name: 'Jim'}
*/
在操作符对象中,如果存在了 value
或 writable
中的任意一个或多个,就不能存在 get
或 set
了。
const obj = {
};
Object.defineProperty(obj, 'name', {
value: 1,
get() {
return 2;
}