JS 中的拦截器 Object.defineProperty

JS 中的拦截器 Object.defineProperty

使用拦截器定义的对象属性, 在该属性操作(读取或赋值)时, 会拦截这一操作, 执行一个操作, 用于指定数据的读取操作(例如限制数据的赋值)
拦截器也可以给对象声明一个不可枚举或不可删除的属性

Object.defineProperty使用语法

Object.defineProperty(obj, attr, options);
  • obj: 操作的对象, 给那个对象声明属性
  • attr: 给对象声明的属性的属性名
  • options: 配置参数
    • value: 属性的值, 一个任意类型的值
    • writable: Boolean, 指定属性是否可以使用赋值运算符"="改变属性值(即是否可写), 默认为false, 不可写
    • enumerable: Boolean, 指定属性是否可以被枚举, 默认为false, 不可枚举
    • configurable: Boolean, 指定属性是否可以被删除, 默认为false, 不可删除
    • get: Function, 读取属性值时会调用该函数, 该函数返回值即为属性值
    • set: Function, 该属性被赋值时会调用该函数, 接收一个参数, 即赋值语句右边的值, 没有该函数或该函数内不会改变get函数返回结果是, 赋值语句无效

注意: 可以使用 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, 属性不可写
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值