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);
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, get: function () { 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 }) }; } });
|
参考