代理 code:Proxy vscode首拼:dl 类型:对象

https://www.jianshu.com/p/77eaaf34e732
前言
Proxy 也就是代理,可以帮助我们完成很多事情,例如对数据的处理,对构造函数的处理,对数据的验证,说白了,就是在我们访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤,由你来定义。

语法
let p = new Proxy(target, handler);
参数

target :需要使用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler: 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器) 。具体的handler相关函数请查阅官网
下面是使用示例,一个简单的代理:

 test = {
    name: "小红"
};
test = new Proxy(test, {
    get(target, key) {
        console.log('获取了getter属性');
        return target[key];
    }
});
console.log(test.name);

无操作转发代理
在以下例子中,我们使用了一个原生 JavaScript 对象,代理会将所有应用到它的操作转发到这个对象上。

let target = {};
let p = new Proxy(target, {});

p.a = 37;   // 操作转发到目标

console.log(target.a);    // 37. 操作已经被正确地转发


验证
通过代理,你可以轻松地验证向一个对象的传值。这个例子使用了 set。

let validator = {
    set: function (obj, prop, value) {
        if (prop === 'age') {
            if (!Number.isInteger(value)) {
                throw new TypeError('The age is not an integer');
            }
            if (value > 200) {
                throw new RangeError('The age seems invalid');
            }
        }

        // The default behavior to store the value
        obj[prop] = value;

        // 表示成功
        return true;
    }
};

let person = new Proxy({}, validator);

person.age = 100;

console.log(person.age);
// 100

person.age = 'young';
// 抛出异常: Uncaught TypeError: The age is not an integer

person.age = 300;
// 抛出异常: Uncaught RangeError: The age seems invalid



实例:

appdata.applist.push(new Proxy({
    name: data.name,
    nodes: [{
        ip: data.ip,
        port: data.port,
        grade: data.grade || 100,
        state: "normal"
    }],
    loadleveling: getloadleveling(data.name),
    timeout: gettimeout(data.name),
    fuse: getfuse(data.name),
    tracepercent: gettracepercent(data.name),
    anomaly: getconfig("anomaly", data.name),
}, {
    get(target, name) {
        if (name == "anomaly") {
            console.log("代理取值");
            return getconfig("anomaly", data.name)
        }
        return target[name]
    }
}
))

通过属性查找数组中的特定对象
以下代理为数组扩展了一些实用工具。可以看到,你可以灵活地“定义”属性,而不需要使用 Object.defineProperties方法。以下例子可以用于通过单元格来查找表格中的一行。在这种情况下,target 是table.rows。

let products = new Proxy([
    { name: 'Firefox', type: 'browser' },
    { name: 'SeaMonkey', type: 'browser' },
    { name: 'Thunderbird', type: 'mailer' }
],
    {
        get: function (obj, prop) {
            // 缺省行为是返回属性值, prop ?通常是一个整数
            if (prop in obj) {
                return obj[prop];
            }

            // 获取 products 的 number; 它是 products.length 的别名
            if (prop === 'number') {
                return obj.length;
            }

            let result, types = {};

            for (let product of obj) {
                if (product.name === prop) {
                    result = product;
                }
                if (types[product.type]) {
                    types[product.type].push(product);
                } else {
                    types[product.type] = [product];
                }
            }

            // 通过 name 获取 product
            if (result) {
                return result;
            }

            // 通过 type 获取 products
            if (prop in types) {
                return types[prop];
            }

            // 获取 product type
            if (prop === 'types') {
                return Object.keys(types);
            }

            return undefined;
        }
    });

console.log(products[0]); // { name: 'Firefox', type: 'browser' }
console.log(products['Firefox']); // { name: 'Firefox', type: 'browser' }
console.log(products['Chrome']); // undefined
console.log(products.browser); // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }]
console.log(products.types); // ['browser', 'mailer']
console.log(products.number); // 3