深切明白ES6笔记(十一)代办(Proxy)和反射(Reflection)API(12)

重要知识点:代办和反射的定义、经常运用的圈套函数、可被打消的代办、将代办对象作为原型运用、将代办作为类的原型

《深切明白ES6笔记(十一)代办(Proxy)和反射(Reflection)API(12)》

《深切明白ES6》笔记 目次

代办与反射

  • 代办是什么?

经由过程挪用 new Proxy() ,你可以建立一个代办用来替换另一个对象(被称之为目目的对象) ,这个代办对目的对象举行了假造,因而该代办与该目的对象表面上可以被看成同一个对象来看待。
代办许可你阻拦目的对象上的底层操纵,而这本来是JS引擎的内部才能,阻拦行动适用了一个能响应特定操纵的函数(被称之为圈套);

  • 反射是什么?

被Reflect对象所代表的反射接口,是给底层操纵供应默许行动的要领的鸠合,这些操纵是可以被代办重写的。每一个代办圈套都有一个对应的反射要领,每一个要领都与对应的圈套函数同名,而且吸收的参数也与之一致。

建立一个简朴的代办

运用Proxy构建可以建立一个简朴的代办对象,须要通报两个参数:目的对象以及一个处理器,后者是定义一个或多个圈套函数的对象。假如不定义圈套函数,则依旧运用目的对象的默许行动:

let target = {};
let proxy = new Proxy(target, {});
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
target.name = "target";
console.log(proxy.name); // "target"
console.log(target.name); // "target"

运用 set 圈套函数考证属性值

假定你想要建立一个对象,并要求其属性值只能是数值,这就意味着该对象的每一个新增属性都要被考证,而且在属性值不为数值范例时应该抛出毛病。为此你须要定义 set 圈套函数来重写设置属性值时的默许行动,该圈套函数能接收四个参数:

  1. trapTarget :将吸收属性的对象(即代办的目的对象);
  2. key :须要写入的属性的键(字符串范例或标记范例);
  3. value :将被写入属性的值;
  4. receiver :操纵发作的对象(通常是代办对象)。

Reflect.set() 是 set 圈套函数对应的反射要领,同时也是 set 操纵的默许行动。
Reflect.set() 要领与 set 圈套函数一样,能接收这四个参数,让该要领能在圈套函数内部被方便运用:

let target = {
    name: "target"
};
let proxy = new Proxy(target, {
    set(trapTarget, key, value, receiver) {
        // 疏忽已有属性,防止影响它们
        if (!trapTarget.hasOwnProperty(key)) {
            if (isNaN(value)) {
                throw new TypeError("Property must be a number.");
            }
        }
        // 增加属性
        return Reflect.set(trapTarget, key, value, receiver);
    }
});
// 增加一个新属性
proxy.count = 1;
console.log(proxy.count); // 1
console.log(target.count); // 1
// 你可认为 name 赋一个非数值范例的值,因为该属性已存在
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
// 抛出毛病
proxy.anotherName = "proxy";

运用 get 圈套函数举行对象外形考证

JS 言语风趣但偶然却令人困惑的特征之一,就是读取对象不存在的属性时并不会抛出毛病,而会把 undefined 看成该属性的值,比方:

let target = {};
console.log(target.name); // undefined

在多半言语中,试图读取 target.name 属性都邑抛出毛病,因为该属性并不存在;但 JS 言语却会运用 undefined 。
对象外形( Object Shape )指的是对象已有的属性与要领的鸠合,因为该属性考证只须在读取属性时被触发,因而只需运用 get 圈套函数。该圈套函数会在读取属性时被挪用,纵然该属性在对象中并不存在,它能接收三个参数:

  1. trapTarget :将会被读取属性的对象(即代办的目的对象);
  2. key :须要读取的属性的键(字符串范例或标记范例);
  3. receiver :操纵发作的对象(通常是代办对象)。

响应的Reflect.get()要领一样具有这三个参数。举行对象外形考证的示例代码:

//import {color,sum,magicNumber} from "./export.js"
import * as example from "./export.js"
console.log(example.color)
console.log(example.magicNumber)

console.log(example.


    sum(76, 2))



let proxy = new Proxy({}, {
    get(trapTarget, key, receiver) {
        if (!(key in receiver)) {
            throw new TypeError("Property " + key + " doesn't exist.");
        }
        return Reflect.get(trapTarget, key, receiver);
    }
});
// 增加属性的功用一般
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
// 读取不存在属性会抛出毛病
console.log(proxy.nme); // 抛出毛病

运用 has 圈套函数隐蔽属性

in运算符用于推断指定对象中是不是存在某个属性,假如对象的属性名与指定的字符串或标记值相匹配,那末in运算符就会返回true。不管该属性是对象本身的属性照样其原型的属性。
has圈套函数会在运用in运算符的情况下被挪用,掌握in运算符返回差别的效果,has圈套函数会传入两个参数:

trapTarget:代办的目的对象;
key:属性键;

Reflect.has()要领吸收雷同的参数,并向in运算符返回默许的响应效果,用于返回默许响应效果。



let target = {
    name: "target",
    value: 42
};
let proxy = new Proxy(target, {
    has(trapTarget, key) {
        if (key === "value") {
            return false;
        } else {
            return Reflect.has(trapTarget, key);
        }
    }
});
console.log("value" in proxy); // false
console.log("name" in proxy); // true
console.log("toString" in proxy); // true
    原文作者:sevencui
    原文地址: https://segmentfault.com/a/1190000016147517
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞