es——Proxy

通常我们说的proxy就是代理,在es6中也是一样,同样作为代理,当我们在使用对象再其他方面时,这变会显得很方便

通常我们说的proxy就是代理,在es6中也是一样,同样作为代理,当我们在使用对象再其他方面时,这变会显得很方便

         简述其中的要领,比如,在一些程序设计中,经常会用到的,用它来做拦截,非常简洁

// proxy

const obj = new Proxy({}, {

    // 将获取值时将会调用该方法

    get(target, key, receiver) {

        console.log('------------------------------------');

        console.log(`getting ${key}`);

        return Reflect.get(target, key, receiver)

        console.log('------------------------------------');

    },

    // 将设置值时将会调用该方法

    set(target, key, receiver) {

        console.log('------------------------------------');

        console.log(`setting ${key}`);

       // Reflect 对象的一种变体,可以这么理解

        return Reflect.set(target, key, receiver)

        console.log('------------------------------------');

    }

})

obj.count = 2 //这里在对obj.count赋值时,会调用上面的set方法 setting count

    ++obj.count

函数的链式操作

// 配置链式操作

const pipe = (function () {

    return function (value) {

        let funcStack = [];

        let oproxy = new Proxy({}, {

            get: function (t, p, r) {

                if (p === 'get') {

                    return funcStack.reduce(function (val, fn) {

                        return fn(val)

                    }, value)

                }

                funcStack.push(tt[p])

                return oproxy

            }

        });

        return oproxy

    }

}())

var tt = {

    double: n => n * 2,

    pow: n => n * n,

    reverseInt: n=>n.toString().split('').reverse().join('')|0

}

console.log('------------------------------------');

console.log(pipe(3).pow.double.reverseInt.get);

console.log('------------------------------------');

设置私有属性不允许访问

// 设置内部属性防止被访问

const exp = (key,action)=>{

    if(key[0]==='_'){

        throw new Error(`Invalid attempt to ${action} private "${key}" property`)

    }

}

const handle = {

    get(t,k,r){

        exp(k,'get')

        return t[k]

    },

    set(t,k,v){

        exp(k,'set')

        t[k]=v

    }

}

const tp = new Proxy({}, handle)

// 不读下划线开头的属性

// tp._xx

其中proxy的实例方法有以下

  • get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。
  • set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
  • has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
  • deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
  • ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
  • getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  • defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
  • preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
  • getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
  • isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
  • setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
  • construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。

这将会是很好的一种方式

Proxy window下的全局方法,直接通过new 操作符来实例化它,一般它会有2个参数,第一个表示拦截哪个对象,第二个参数对象中表示拦截的一些方法,常见的为get跟set方法,其中

get方法中会有3个参数,分别表示目标对象,就是需要代理的那个对象target,第二个表示属性,代理target获取的当前属性prop,第三个receiver 表示的是当前proxy对象实例

         set方法中携带4个参数,分别是目标对象target,属性键key属性值value,代理实例receiver

百度未收录
分享