40

ES6:Proxy Reflect

 4 years ago
source link: https://www.tuicool.com/articles/MneIZnM
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Proxy

定义:Proxy 可以理解为在目标对象之外加一层“拦截”,外界对该对象的访问,都必须会先经过这一层拦截,因些我们可以对外界的访问做一些改写与过滤,可译为“代理器”。

var proxy = new Proxy(target, handler);

target 就是想要代理的目标对象,handler 则是一个方法,在其中定义想要代理的一些操作。常用可代理操作列表如下:

  • get(target, property, receiver),拦截对象属性的读取
  • set(target, property, value, receiver),拦截对象属性的设置
  • has(target, property),拦截 property in target 的操作,返回一个布尔值
  • deleteProperty(target, property),拦截 delete target[property]的操作,返回一个布尔值
  • defineProperty(target, property, prop),拦截 Object.defineProperty 的操作,返回一个布尔值
  • apply(target, object, args),拦截 函数的调用 、call 和 apply 操作

更多操作可查看MDN: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

实际使用场景:

  • 实现私有变量的访问拦截
let person = {
    name: 'test',
    age: 23,
    _privateName: 'private name',
    _phone: '13888888888'
}
let personProxy = new Proxy(person, {
    get(target, prop) {
        if(prop.startsWith('_')){
            console.log('私有变量禁止访问');
            return false;
        }
        return target[prop];
    },
    set(target, prop, value) {
        if(prop.startsWith('_')) {
            console.log('私有变量禁止修改');
            return false;
        }
        target[prop] = value;
    },
    has(target, prop) {
        return prop.startsWith('_') ? false : (prop in target);
    }
})
personProxy._phone;   // 私有变量禁止访问
personProxy._phone = '13999999999';   // 私有变量禁止修改
'_phone' in personProxy;   // false
'name' in personProxy;    // true
  • 设置对象属性前进行校验
let person = {
    phone: ''
}
let personProxy = new Proxt(person, {
    set(target, prop, value) {
        if(prop === 'phone') {
           let reg = 'xxx';
           if(!reg.test(value)){
               throw Error('validate error!')
           }
        }
        target[prop] = value;
    }
})
  • Observe Function
function observe(obj, callback) {
    return new Proxy(obj, {
        set(target, prop, value) {
            callback(prop, value);
            target[prop] = value;
        }
    })
}
const bar = { open: false}
const barObserve = observe(bar, (prop, value) => {
    prop === 'open' && value ? alert('Opening!') : console.log('Waiting');
})
barObserve.open = true;  //  'Opening!'

Reflect

Reflect的方法与Proxy的方法一一对应 ,它可以让对 Object 的一切操作都变成函数形为;比如 key in object => Reflect.has(key)、delect object[key] => Reflect.deleteProperty(object, key)。

let proxy = new Proxt({}, {
    get(target, prop) {
        return Reflect.get(target, name);
    },
    set(target, prop, value) {
        Reflect.set(target, prop, value);
    },
    has(target, prop) {
        return Reflect.has(target, prop);
    },
    deleteProperty(target, prop) {
        return Reflect.deleteProperty(target, prop);
    }
})

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK