每天做个总结吧,坚持就是胜利!
/**
@date 2021-06-19
@description Object.defineProperty()小结
*/
复制代码
壹(序)
Object的defineProperty
方法,用于在一个对象上新增或修改属性
,通过Object.defineProperty()调用,而不是在一个对象实例上调用,因为它是Object的直接方法,而不是prototype
上的方法。
defineProperty方法接受三个参数:
-
需要处理的对象(obj);
-
该对象需要处理的属性名或Symbol(prop);
-
需要修改的属性描述符(descriptor();
)
返回完成操作后的对象。
贰(与.操作符或[]操作符区别)
对象也能使用.
操作符或[]
操作符去新增或修改一个属性,但是使用defineProperty能够进行更多的操作,比如该属性是否可枚举(enumerable),是否可配置(configurable)等,主要在于第三个参数;
descriptor
(描述符)分为两种,数据描述符与存取描述符;
传入的描述符只能是其中一种,两种描述符共同的参数是:
/**
* enumerable: 是否可枚举(能否使用for...in或Object.keys()读取),默认为false;
* configurable: 是否可配置,能否修改描述符,能否删除,默认为false;
*/
复制代码
而数据描述符特有的参数是:
/**
* value: 当前对象当前属性的值,默认为undefined;
* writable: 是否可写(能否修改value),默认为false;
*/
// 测试
const obj = {};
Object.defineProperty(obj, 'a', {
enumerable: true,
configurable: true,
value: 1,
writable: true,
})
Object.keys(obj); // ['a']
Object.defineProperty(obj, 'a', {
enumerable: false,
configurable: true,
value: 1,
writable: true,
})
Object.keys(obj); // []
obj.a = 2;
console.log(obj); // {a: 2}
Object.defineProperty(obj, 'a', {
enumerable: false,
configurable: true,
value: 1,
writable: false,
})
obj.a = 2;
console.log(obj); // {a: 1}
Object.defineProperty(obj, 'b', {
enumerable: false,
configurable: false,
value: 1,
writable: false,
})
delete obj.a; // true
delete obj.b; // false
复制代码
存取描述符特有的参数是:
/**
* get: 属性的getter函数,必须是一个函数,否则报错,如果没有此函数则返回undefined
* 有的话调用此函数,返回函数返回值;默认为undefined;
* set: 属性的setter函数,也必须是一个函数,否则报错,修改属性值时调用此函数
* 此函数中this是当前对象;默认为undefined
*/
// 测试
const obj = {};
let value = 1;
Object.defineProperty(obj, 'b', {
enumerable: true,
configurable: true,
get: function() {
return value;
},
set: function(newValue) {
value = newValue * newValue;
},
})
console.log(obj.b); // 1
obj.b = 2;
console.log(obj.b); // 4
复制代码
叁(引申,来自《你不知道的JS上》)
- 对象常量
/**
* 将一个对象的属性设置成一个常量(不可修改,不可删除)
*/
const obj = {};
Object.defineProperty(obj, 'a', {
value: 1,
writable: false,
configurable: false,
enumerable: true, // 原文没有,自己认为需要是可枚举的
})
复制代码
- 禁止扩展
/**
* 禁止一个对象添加新属性,可以使用Object.preventExtensions()
*/
const obj = {a: 1};
Object.preventExtensions(obj);
console.log(obj); // {a: 1}
obj.b = 2;
console.log(obj); // {a: 1}
复制代码
- 密封
/**
* 使用Object.seal()将一个对象密封起来,该对象将不能添加,删除属性,也不可重新配置,可以修改
* 实际上是调用Object.preventExtensions()以及设置所有属性的configurable为false
*/
复制代码
- 冻结
/**
* 使用Object.freeze()可以将一个对象冻结,该对象将不能添加,修改,删除,配置
* 实际上是调用Object.seal()并把所有的数据访问属性的writable置为false
* 注意,getter和setter是不受影响的,其次,是可以修改该对象的引用属性的。
*/
const obj = {a: 1, c: {d: 3}};
let b = 2;
Object.defineProperty(obj, 'b', {
get: function() { return b },
set: function(val) { b = val }
});
Object.freeze(obj);
obj.a = 3;
console.log(obj.a); // 1
obj.b = 4;
console.log(obj.b); // 4
obj.c.d = 5;
console.log(obj.c.d); // 5
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END