使用拦截器定义的对象属性, 在该属性操作(读取或赋值)时, 会拦截这一操作, 执行一个操作, 用于指定数据的读取操作(例如限制数据的赋值)
拦截器也可以给对象声明一个不可枚举或不可删除的属性
Object.defineProperty(obj, attr, options);
注意: 可以使用 value + writable 定义属性的值和写入状态, 也可以使用 get + set 定义属性的值和写入状态, 但是不能同时使用 vale + writable 和 get + set, 这样会报错
定义一个对象obj, 并写入一个属性name, 只定义options中的value, (writable, enumerable, configurable默认为false, 该属性不可写, 不可枚举, 不可删除)
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'eno',
});
console.log('name: ', obj.name); // eno
obj.name = 'zeng'; // 尝试使用赋值语句改变name的值
console.log('name: ', obj.name); // eno, name属性的值没有被改变
// 尝试遍历obj的属性
var arr = [];
for(var key in obj) { // ES6语法, 用于遍历对象
arr.push(obj[key]);
}
console.log('arr: ', arr); // arr为空数组, 证明obj中的属性无法被枚举
delete obj.name;
console.log('name', obj.name); // eno, 属性无法使用delete删除
定义一个对象obj, 并写入一个属性name, 定义name属性可赋值, 可枚举, 可删除
var obj = {}
Object.defineProperty(obj, 'name', {
value: 'eno',
writable: true,
enumerable: true,
configurable: true
});
console.log('name: ', obj.name); // eno
obj.name = 'zeng'; // 尝试使用赋值语句改变name的值
console.log('name: ', obj.name); // zeng, name属性的值被改变
// 尝试遍历obj的属性
var arr = [];
for(var key in obj) {
arr.push(obj[key]);
}
console.log('arr: ', arr); // ['zeng'], 证明obj中的name属性可以被枚举
delete obj.name;
console.log('name', obj.name); // undefined, 属性可以使用delete删除
使用 get 和 set 函数定义一个可读可写属性, 并在读写操作是执行一个打印输出
var obj = {}
var name = 'eno';
Object.defineProperty(obj, 'name', {
get() {
console.log('读取obj的name属性值');
return name;
},
set(newVal) {
console.log('改变obj的name属性值, 新属性值为: ', newVal);
name = newVal;
}
});
console.log('name: ', obj.name); // eno, 输出eno前会执行get函数中的 console.log 语句
obj.name = 'zeng';
console.log('name: ', obj.name); // zeng, 输出zeng前会依次执行 set 和 get 函数中的 console.log 语句
没有 set 函数, 只有 get 函数, 属性只读
var obj = {}
var name = 'eno';
Object.defineProperty(obj, 'name', {
get() {
console.log('读取obj的name属性值');
return name;
}
});
console.log('name: ', obj.name); // eno, 输出eno前会执行 get 函数中的 console.log 语句
obj.name = 'zeng';
console.log('name: ', obj.name); // eno, 属性不可写