神奇的Object.defineProperty()
作者:互联网
Object.defineProperty()可以动态地给对象定义属性, 可以实现数据代理.
Object.defineProperty(obj, prop, descriptor)的3个参数:
- obj 代表要定义属性的对象
- prop代表要定义的属性名
- descriptor代表关于属性的配置, 包括是否可枚举, 是否可删除, 是否可修改, setter, getter.
以下代码动态地给obj对象添加了age属性
1 let obj = { 2 name: "小红" 3 } 4 5 Object.defineProperty(obj, "age", { 6 value: 18 7 }) 8 9 console.log(obj) // {"name":"小红"}, age属性虽然添加上了, 但是因为age属性默认不可枚举, 所以没有打印出来 10 console.log(obj.age) // 18 11 console.log(delete obj.age) // false, age属性默认无法被删除 12 obj.age = 19 // 尝试将age属性的值改成19 13 console.log(obj.age) // 还是18, 上一行虽然给age属性赋值了, 但是因为age属性默认不可修改, 所以没有赋值成功
上面代码的注释中做了一些说明.
如果想要age属性可枚举, 只要在descriptor中增加enumerable为true即可.
如果想要age属性可删除, 只要在descriptor中增加configurable为true即可.
如果想要age属性可修改, 只要在descriptor中增加writable为true即可.
1 let obj = { 2 name: "小红" 3 } 4 5 Object.defineProperty(obj, "age", { 6 value: 18, 7 enumerable: true, 8 configurable: true, 9 writable: true 10 }) 11 12 console.log(obj) // {"name":"小红","age":18} 13 console.log(obj.age) // 18 14 console.log(delete obj.age) // true, age属性无法被删除 15 obj.age = 19 // 尝试将age属性的值改成19 16 console.log(obj.age) // 19
下面介绍descriptor中2个最神奇的属性: get 和 set
顾名思义, get方法就是获取属性的值, 没有参数; set方法就是设置属性的值, 有一个参数用来接收传来的值.
1 let obj = { 2 name: "小红" 3 } 4 5 let obj2 = { 6 age: 18 7 } 8 9 Object.defineProperty(obj, "age", { 10 get() { 11 return obj2.age 12 }, 13 set(value) { 14 obj2.age = value 15 } 16 }) 17 18 console.log(obj.age) // 此处会调用get方法, 返回的是obj2.age 19 obj.age = 19 // 修改obj.age的值, 通过下面两行代码发现obj2.age也被修改了 20 console.log(obj.age) // 19 21 console.log(obj2.age) // 19 22 obj2.age = 20 // 修改obj2.age的值, 通过下面两行代码发现obj.age也被修改了 23 console.log(obj.age) // 20 24 console.log(obj2.age) // 20
上面的代码中, obj与obj2的age属性已经绑定在一起, 修改其中一个就会影响到另一个, 也就是实现了一个简单的数据代理.
最后, 需要注意的是, get 和 set 不能与value 和 writable一起使用, 否则会报异常, 猜测是因为都影响了属性值的获取和修改, 所以不能一起使用.
标签:obj2,obj,log,age,Object,defineProperty,console,神奇,属性 来源: https://www.cnblogs.com/yuandaguangming/p/16330578.html