JS的Object.defineProperty用法

Object.defineProperty用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象。

属性描述符

属性 默认值 说明
configurable false 描述属性是否可以被删除,默认为 false
enumerable false 描述属性是否可以被for…in或Object.keys枚举,默认为 false
writable false 描述属性是否可以修改,默认为 false
get undefined 当访问属性时触发该方法,默认为undefined
set undefined 当属性被修改时触发该方法,默认为undefined
value undefined 属性值,默认为undefined

案例

Object.defineProperty()默认定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var obj = {};
console.log('obj:', obj);

// 默认不可删除,不可枚举,不可修改
Object.defineProperty(obj, 'name', {
value: 'Jameswain'
});
console.log('obj默认值:', obj);
delete obj.name;
console.log('obj删除后:', obj);
console.log('obj枚举:', Object.keys(obj));
obj.name = '詹姆斯,韦恩';
console.log('obj修改后:', obj);
// 不能重新定义,会报重复定义错误: Uncaught TypeError: Cannot redefine property: name
Object.defineProperty(obj, 'name', {
value: '詹姆斯,韦恩'
});

运行结果:

1
2
3
4
5
6
7
8
obj: {}
obj默认值: {name: 'Jameswain'}
obj删除后: {name: 'Jameswain'}
obj枚举: []
obj修改后: {name: 'Jameswain'}
Uncaught TypeError: Cannot redefine property: name
at Function.defineProperty (<anonymous>)
at <anonymous>:15:8

从运行结果可以发现,使用Object.defineProperty()定义的属性,默认是不可以被修改,不可以被枚举,不可以被删除的。

set和get用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const o = {
__name: ''
};
Object.defineProperty(o, 'name', {
enumerable: true,
configurable: true,
// writable: true, // 如果设置了get或者set,writable和value属性必须注释掉
// value: '', // writable和value无法与set和get共存
get: function () { // 如果设置了get或者set就不能设置writable和value
console.log('get', this);
return 'My name is ' + this.__name;
},
set: function (newVal) {
localStorage.setItem('name', newVal);
console.log('set', newVal);
this.__name = newVal;
}
});
console.log(o);
o.name = 'Jameswain';
o.name;
console.log(o);
o.name = '詹姆斯-韦恩';
console.log(o);

运行结果:

1
2
3
4
5
6
7
{__name: ''}
set Jameswain
get {__name: 'Jameswain'}
{__name: 'Jameswain'}
set 詹姆斯-韦恩
{__name: '詹姆斯-韦恩'}
undefined

注意:设置set或者get,就不能在设置value和writable,否则会报错

实际应用-Fetch拦截

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 保存一份旧的引用地址
const originFetch = window.fetch;

Object.defineProperty(window, "fetch", {
configurable: true,
enumerable: true,
get() {
return (url: string, options: any = {}) => {
return originFetch(url, options)
.then((res) => {
// 自定义操作,比如计算接口耗时
// ...
return res
})
};
}
});

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道