它是JS的内置对象,开发者可以通过调用这些方法,访问一些JS底层原理。
使用Reflect可以实现诸如 属性的赋值与取值、调用普通函数、调用构造函数、判断属性是否存在与对象中 等等功能
这些功能不是已经存在了吗?为什么还需要用Reflect实现一次?
有一个重要的理念,在ES5就被提出:减少魔法、让代码更加纯粹
这种理念很大程度上是受到函数式编程的影响
ES6进一步贯彻了这种理念,它认为,对属性内存的控制、原型链的修改、函数的调用等等,这些都属于底层实现,属于一种魔法,因此,需要将它们提取出来,形成一个正常的API,并高度聚合到某个对象中,于是,就造就了Reflect对象
因此,你可以看到Reflect对象中有很多的API都可以使用过去的某种语法或其他API实现。
const obj = {
a: 1,
}
Reflect.set(obj,'b',1221);
console.log(Reflect.get(obj,'b')); // 1221
代理:提供了修改底层实现的方式
//代理一个目标对象
//target:目标对象
//handler:是一个普通对象,其中可以重写底层实现
//返回一个代理对象
new Proxy(target, handler)
const obj = {
a: 1,
b: 2
}
// 通过操作obj的代理,来间接操作obj
const objProxy = new Proxy(obj, {
set(target, propertyKey, value) {
Reflect.set(target, propertyKey, value);
},
get(target, propertyKey) {
if (Reflect.has(target, propertyKey)) {
return Reflect.get(target, propertyKey);
} else {
return -1;
}
},
has(target, propertyKey) {
return false;
}
})
objProxy.a = 123;
console.log('a' in objProxy); // false
console.log(objProxy.a); // 123
有一个对象,是观察者,它用于观察另外一个对象的属性值变化,当属性值变化后会收到一个通知,可能会做一些事。
function observer(target) {
const ob = {};
const div = document.getElementById('container');
const props = Object.keys(target);
for (const prop of props) {
Object.defineProperty(ob, prop, {
get() {
return target[prop];
},
set(val) {
target[prop] = val;
render();
},
enumerable: true
})
}
render();
function render() {
let html = '';
for (const prop of Object.keys(ob)) {
html += `${prop}: ${ob[prop]}
`
}
div.innerHTML = html;
}
return ob;
}
const target = {
a: 1212,
age: 24
}
const obj = observer(target);
使用Object.defineProperty会增加一个新的对象。直接改变target无法监听。
//创建一个观察者
function observer(target) {
const div = document.getElementById("container");
const proxy = new Proxy(target, {
set(target, prop, value) {
Reflect.set(target, prop, value);
render();
},
get(target, prop){
return Reflect.get(target, prop);
}
})
render();
function render() {
let html = "";
for (const prop of Object.keys(target)) {
html += `
${prop}:${target[prop]}
`;
}
div.innerHTML = html;
}
return proxy;
}
const target = {
a: 1,
b: 2
}
const obj = observer(target)
proxy不会增加一个新的对象,会监听所有属性改变。
class User {
}
function ConstructorProxy(className, ...propName) {
return new Proxy(className, {
construct(target, argumentsList) {
const obj = Reflect.construct(target, argumentsList);
propName.forEach((name, i)=>{
obj[name] = argumentsList[i+1];
})
return obj;
}
})
}
const userConstructor = ConstructorProxy(User, 'firstName', 'lastName', 'age');
const obj = new userConstructor(User, 'chou', 'jay', 18);
console.log(obj);
// User { firstName: 'chou', lastName: 'jay', age: 18 }
function sum(a, b) {
return a + b;
}
function validatorFunction(func, ...types) {
const proxy = new Proxy(func, {
apply(target, thisArgument, argumentsList) {
types.forEach((t, i) => {
const arg = argumentsList[i]
if (typeof arg !== t) {
throw new TypeError(`第${i+1}个参数${argumentsList[i]}不满足类型${t}`);
}
})
return Reflect.apply(target, thisArgument, argumentsList);
}
})
return proxy;
}
const sumProxy = validatorFunction(sum, "number", "number")
console.log(sumProxy(1, 2))