首先了解一下属性描述符
属性描述符
属性描述符,是一个普通对象,用于描述一个属性的相关内容
通过Object.getOwnPropertyDescriptor(对象,属性名) 通过一个对象得到某个对象中一个属性描述符
通过Object.getOwnPropertyDescriptors(对象) 通过一个对象得到某个对象中所有属性的属性描述符
-
value:属性值 -
configurable:该属性的属性描述符里面的属性是否可以修改 -
enumerable:该属性是否可以被枚举(就是罗列出来看,在for in,Object.keys(),Object.values无效果) -
writable:该属性的值是否可以被重新赋值
为某个对象添加属性时 或 修改属性时
通过Object.defineProperty函数
let obj = {
name:"sdy",
age:20
}
// 第一种写法 Object.defineProperty(对象,属性,属性描述符)
Object.defineProperty(obj, name, {
value:"hello world"
})
//configurable使用
设置为false后,不可以修改属性描述符内容(除了value)
Object.defineProperty(obj, "name", {
value: "可以修改",
configurable: false,
enumerable: true,
})
Object.defineProperty(obj, "name", {
value: "不可以修改",
configurable: false,
enumerable: true,
})
//第二种写法 Object.defineProperties(obj, {
name: {},
age:{}
})
存取器属性
普通的属性的属性值放在内存中的,存取器属性的值是在访问时运行get方法,设置时运行set方法
在属性描述符中,设置了get与set中的任意一个属性,那么这个属性,就变成一个存取器属性
在读取这个属性的时候,会运行get的方法,得到的是get函数的返回值
在设置这个属性的时候会运行set方法
注意get与set不能与????????value ,writable共存
let obj = {
name: "sdy",
age: 20
}
Object.defineProperty(obj, "name", {
get() {
return obj._a;
},
set(val) {
obj._a = val;
}
})
obj.name = '存取器属性';
存取器属性最大的意义,在于可以控制属性的读取和赋值。
反射 Reflect
var obj = {
name:'sdy'
}
function test(a,b) {}
//设置一个对象某个属性的值
//Reflect.set(对象, 属性, 值)
Reflect.set(obj, 'name', yyy);
//得到一个对象某个属性的值
//Reflect.get(对象, 属性)
//函数的调用
//Reflect.apply(函数名, this指向, [参数])
Reflect.apply(test, null, [1,2]);
其他见
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
Reflect是一个内置的js对象
reflect很大的程度上是为了减少js的魔法(原型链之类)
代理 Proxy
代理:提供了修改底层实现的方式
//new Proxy(代理的目标对象,从写底层实现的对象)
//可以重写所有反射里面的方法
//返回一个代理对象
let o = {
name: 'sdy',
age: 20,
sex: 'male'
}
let proxy = new Proxy(o, {
set(obj, attr, arg) {
obj[attr] = arg;
}
});
proxy.name = '阿德啊啊';
console.log(proxy.name);
//另一种写法
let proxy = new Proxy(o, {
set(obj, attr, arg) {
//经过一些处理
Reflect.set(obj, attr, arg);
}
});
|