=========================反射======================= Reflect: 反射 1. Reflect是什么: Reflect是一个内置的JS对象,它提供了一系列方法,可以让开发者通过调用这些方法,访问JS底层功能 由于它类似于其他语言的反射,因此取名为Reflect 2. 它可以做什么? 使用Reflect可以实现属性的取值,赋值,调用普通函数,调用构造函数,判断属性是否存在与对象中等 3.这些功能存在,为啥还有重复实现一次? ES5中提出一个概念: 减少魔法,让代码更加纯粹 这种理念很大程度上是受到了函数式编程的影响: plus(add(3)(2))(6) ES6进一步贯彻这种理念,它任务,对属性内存的控制,原型链的修改,函数的调用等, 这些都属于底层实现,属于一种魔法,因此,需要将他们提取出来,形成一个正常的API, 并高度聚合到某个对象中,于是就造就了Reflect对像 4. 它到底提供了哪些API呢? Reflect.set(target,propertyKey, value): 设置对象target的属性propertyKey里面的value, 相当于对象.属性 = 赋值; 例如: const obj = { a: 1, } // 赋值 obj.a = 10; // 等效于 Reflect.set(obj, 'a', 10) Reflect.get(target, key) : 读取对象target对象的属性propertyKey,等同于获取对象的属性值 例如: const obj = { a: 1, } // 赋值 console.log(obj.a) // 等效于 console.log(Reflect.get(obj, 'a')) Reflect.apply(target, thisArgument, argumentsList): 调用一个指定的函数,等效于绑定this和参数裂掉。等效于函数调用 例如: function methonds(a){ console.log("打印",a) } methonds(3); Reflect.apply(methonds, null, [3]) Reflect.deleteProperty(obj, propertyKey): 删除一个对象里面的key和value, 相等于 delete Reflect.defineProperty(target, propertyKey, attribute): 类似于Object.defineProperty, 不同的式如果配置出现问题,返回false而不是报错 Reflect.construct(target, arguementList) : 用构造函数创建一个对象 Reflect.has(target, key): 判断一个属性是否包含某个对象,相当于 in ======================代理=========================== 代理: 修改了底层实现的方式 使用方法: // 代理一个目标对象 new Proxy(target, handler) 两个参数: target: 目标对象 handler: 是一个普通对象,其中可以重写底层实现 返回一个代理对象 例如: const obj2 = { a: 1, b: 2 } const proxy = new Proxy(obj, { set(target, propertyKey, value) { // target[propertyKey] = value; Reflect.set(target, propertyKey, value) }, get(target, propertyKey){ if(Reflect.has(target, propertyKey)){ retrun Reflect.get(target, propertyKey); }else{ retrun -1; } } }) console.log(proxy) 用代理和反射实现一些例子,常用的功能 // 观察者模式 // 有一个对象,是观察者,它用于观察另外一个对象的属性值变化,当属性值变化后会受到通知,可能会做一些事情 function observer(target) { render(); const proxy = new Proxy(target, { set(target, propertyKey, value) { Reflect.set(target, propertyKey, value); render(); }, get(target, propertyKey) { Reflect.get(target, propertyKey); } }) function render() { let htmlStr = ""; for (const item of Object.keys(target)) { htmlStr += `<span>${item}:</span><span>${target[item]}</span></br>` } document.body.innerHTML = htmlStr; } return proxy; } const obj = { a: 1, b: 2, } const result = observer(obj); console.log(result); // 手写一个给构造函数赋值的方法 function proxyConstructor(className, ...agrs) { return new Proxy(className, { construct(className, agrsList) { const constructObj = Reflect.construct(className, agrs); for (const item in agrs) { Reflect.set(constructObj, agrs[item], agrsList[item]); } return constructObj; } }) } class User { } const userProxy = proxyConstructor(User, "name", "age", "sex"); const user = new userProxy("twinkle", 18, '男'); console.log(user) // 实现一个函数验证器 function proxyValication(funcName, ...agrs) { return new Proxy(funcName, { apply(funcName, thisArgument, argumentsList) { // 验证参数类型是否符合要求 argumentsList.forEach((item, index) => { if (typeof item !== agrs[index]) { throw new TypeError(`第${index + 1}参数${argumentsList[index]}不是${agrs[index]}类型`) } }) return Reflect.apply(funcName, thisArgument, argumentsList); } }) } function sum(a, b) { return a + b; } const sumProxy = proxyValication(sum, "number", "number"); const resultSum = sumProxy(1, 5898); console.log(resultSum); `` > ![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200623194241732.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNDk5Nzgy,size_16,color_FFFFFF,t_70)