美文网首页
ES6(Proxy和Reflect)

ES6(Proxy和Reflect)

作者: 陈裔松的技术博客 | 来源:发表于2019-03-29 08:29 被阅读0次

Proxy

代理,用于连接用户与真实的对象。通过代理,可以根据不同的业务逻辑,做相应的处理。

// 目标对象
let obj = {
    time: '2017-03-11',
    name: 'net',
    _r: 123
}

// 新建一个代理,代理对象:obj
let monitor = new Proxy(obj, {
    // 拦截对目标对象属性的读取
    // target:目标对象(obj),key:想要读取的属性
    get(target, key) {
        return target[key].replace('2017', '2018');
    },
    // 拦截对目标对象属性的设置
    // target:目标对象(obj),key:想要设置的属性,value:想要设置的值
    set(target, key, value) {
        // 自定义限制:只允许修改name属性
        if (key === 'name') {
            return target[key] = value;
        } else {
            return target[key];
        }
    },
    // 拦截key in object操作
    has(target, key) {
        // 自定义限制:只暴露name属性
        if (key === 'name') {
            return target[key];
        } else {
            return false;
        }
    },
    // 拦截对目标对象属性的删除
    deleteProperty(target, key) {
        // 自定义限制:只允许删除_开头的属性
        if (key.indexOf('_') > -1) {
            delete target[key];
            return true;
        } else {
            return target[key];
        }
    },
    // 拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
    ownKeys(target){
        return Object.keys(target).filter(item => item != 'time');
    }
});

console.log(monitor.time);      // 2018-03-11   2017已经被替换成2018

monitor.time = '2018';
console.log(monitor.time);      // 2018-03-11   修改time属性失败

monitor.name = 'song';
console.log(monitor.name);      // song         修改name属性成功

console.log('name' in monitor); // true         暴露
console.log('time' in monitor); // false        未暴露

delete monitor.time;
console.log(monitor);           // Proxy {time: "2017-03-11", name: "song", _r: 123}
delete monitor._r;
console.log(monitor);           // Proxy {time: "2017-03-11", name: "song"}

console.log(Object.keys(monitor));  // ["name"]

Reflect

映射,用于映射真实的对象。其拥有的方法与Proxy的方法完全一致。

let obj = {
    time: '2017-03-11',
    name: 'net',
    _r: 123
}

console.log(Reflect.get(obj, 'name'));  // net
Reflect.set(obj, 'name', 'song');
console.log(Reflect.get(obj, 'name'));  // song
console.log(Reflect.has(obj, 'name'));  // true

使用场景(数据校验)

// 与传统校验方式相比,这种方式把校验规则单独抽离出来,减少与业务逻辑的耦合

// 通用代理生成函数
function validator(target, validator) {
    return new Proxy(target, {
        _validator: validator,
        set(target, key, value, proxy) {
            if (target.hasOwnProperty(key)) {
                let va = this._validator[key];
                if (!!va(value)) {
                    return Reflect.set(target, key, value, proxy);
                } else {
                    throw Error(`不能设置${key}到${value}`);
                }
            } else {
                throw Error(`${key}不存在`);
            }
        }
    })
}

// 校验规则
const personValidators = {
    name(val) {
        return typeof val === 'string';
    },
    age(val) {
        return typeof val === 'number' && val > 18;
    }
}

// 类Person实例化之后,得到的是一个对Person实例对象的代理
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
        return validator(this, personValidators); // this指向的是类的实例
    }
}

const person = new Person('lilei', 30);

console.log(person);    // Proxy {name: "lilei", age: 30}

person.name = 48;       // Uncaught Error: 不能设置name到48

相关文章

  • ES6——Reflect 与 Proxy

    ES6 之 Proxy 介绍深入实践 ES6 Proxy & Reflect 1.Proxy Proxy 可以对目...

  • ES6中的Reflect与Proxy(个人笔记)

    概述 Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。 Proxy:Proxy 可以对目...

  • (二)16.Proxy和Reflect19-08-13

    Proxy和ReflectProxy和Reflect的概念Proxy :代理Reflect:反射 Proxy 打印...

  • 使用Reflect和Proxy编写的值校验。

    可以使用Reflect和Proxy编写脱离值本身的校验,便于维护与重构。代码如下: ES6中新增的Reflect怎...

  • ES6标准入门读书笔记12(Reflect)未完待续

    概述 § ⇧ Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect...

  • Reflect

    概述 § ⇧ Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect...

  • ES6 Proxy和Reflect

    Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。Proxy 可以对目标对象的读取、函数调...

  • Reflect 对象

    Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新的API。Reflect 对象的...

  • ES6 Reflect

    一、概述 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象...

  • Reflect对象

    Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的...

网友评论

      本文标题:ES6(Proxy和Reflect)

      本文链接:https://www.haomeiwen.com/subject/smdkbqtx.html