目录↑

ES6-Proxy

By blockXun

Proxy 代理 ,在我们访问对象前添加了一层拦截,可以过滤很多操作

let a = new Proxy(target, handler);
  • target: 需要包装的对象,可以是数组、函数、class类、Proxy等
  • handler: 传入一个对象,对target进行的具体操作

以Proxy的get示例

get

let obj = {
    val: 'aaa'
}
let proxyObj = new Proxy(obj,{
    get(target, key) {
        return target[key] + '我被代理过了'
    }
})
console.log(proxyObj.val)
// aaa我被代理过了

创建一个obj,然后对其属性进行get监听,obj成为了proxyObj的实例,访问obj属性时,需要写proxyObj.xxx 这样就会被proxy拦截

get可以对所有属性进行拦截,无论是已创建的还是未创建的

// 接上一个例子
...
obj.b = 'bbb'
console.log(proxyObj.b)
// bbb我被代理过了
proxyObj.c
// undefined我被代理过了
proxyObj.c = 'ccc'
console.log(proxyObj.c)
// ccc我被代理过了

从上例中可以看出,无论是在obj中新赋值的属性,还是proxyObj中新赋值的属性,都可以被get监听到

set

const obj = {};
const a = new Proxy(obj, {
    set(target, prop, value){
        target[prop] = value + '我被代理过了';
        // return true;
    }
})
a.a = 'aaa';
// aaa
console.log(a.a)
// aaa我被代理过了

set可以监听目标对象的所有属性赋值行为。如果目标对象自身的某个属性是不可写也不可配置的,那么 set 不得改变这个属性的值,只能返回同样的值,否则报错。

apply

apply可以监听调用时的行为

var fun = function (a,b) {
    return a + b
}
var a = new Proxy(fun, {
    apply(target, thisArg, args) {
        console.log('target', target)
        console.log('thisArg', thisArg)
        console.log('args', args)
        return target.call(thisArg, ...args)
    }
})
a(1,2)
// 'target' ƒ (a,b) { return a + b }
// 'thisArg' undefined
// 'args' [1, 2]

// 3
window.a(1,2)
// 'target' ƒ (a,b) { return a + b }
// 'thisArg' window {...}
// 'args' [1, 2]

// 3

apply中的参数

  • target 原始的函数
  • thisArg 调用时指向的this对象
  • args 调用时取得的形参

construct

construct可以监听目标对象在new时的执行

class a {}
var c = new Proxy(a, {
    construct(target, args, newTarget) {
        console.log('target', target)
        console.log('args', args)
        console.log('newTarget', newTarget)
        return {args: args}
    }
})
new c(1,2,3)
// target class a {}
// args [1, 2, 3]
// newTarget Proxy {length: 0, prototype: {…}, name: "a"}

// {args: Array(3)}

construct中的参数和返回值

  • target 原始的class类
  • args 调用时取得的形参
  • newTarget new target所得
  • return 返回new所得到的实例

Proxy的其他属性

引自PHP中文网的不言大神的博客

Proxy的其他属性

get、set监听时,Proxy和Object.definePrototype的区别

Object.defineProperty

  1. 只能劫持对象的属性,如果属性也是对象需要深度便利
  2. 对数组监听,无法监听到他的变化
  3. 只能对对象中的单个属性监听
  4. 除了get、set,还有configurable、enumerable、value

Proxy

  1. Proxy需要创建一个新对象,监听后所有的操作需要在新对象上执行
  2. 会监听到对象中所有属性(可读写的)
  3. 除了get、set,还有apply、construct等很多属性