前端小白成长05--Proxy

2020-05-17  本文已影响0人  Clover园

JavaScript中的Proxy

翻译过来就是代理的意思,Proxy是ES6中提供的新的API,可以用来定义对象各种基本操作的自定义行为 (在文档中被称为traps),拿它可以做很多有意思的事情,在我们需要对一些对象的行为进行控制时将变得非常有效。

Proxy的语法

创建一个Proxy的实例需要传入两个参数

1.target 要被代理的对象,可以是一个object或者function

2.handlers对该代理对象的各种操作行为处理,可以称为处理对象

defineProperty和proxy区别

class Test {
    constructor (a, b) {
        console.log('constructor', a, b)
    }
}

// Test(1, 2) // throw an error

let proxyClass = new Proxy(Test, {apply (target, thisArg, argumentsList) {

        // 如果想要禁止使用非new的方式来调用函数,直接抛出异常即可
    
        // throw new Error(`Function ${target.name} cannot be invoked without 'new'`)
    
        return new (target.bind(thisArg, ...argumentsList))()

    }
})
proxyClass(1, 2) // constructor 1 2

我们使用了apply来代理一些行为,在函数调用时会被触发,因为我们明确的知道,代理的是一个Class或构造函数,所以我们直接在apply中使用new关键字来调用被代理的函数。

以及如果我们想要对函数进行限制,禁止使用new关键字来调用,可以用另一个trap:construct

function add (a, b) {
    return a + b
}
let proxy = new Proxy(add, {
    construct (target, argumentsList, newTarget) {
        throw new Error(`Function ${target.name} cannot be invoked with 'new'`)
    }
})
proxy(1, 2) // 3
new proxy(1, 2) // throw an erro

还有一些对象的方法

最长用的也是vue用的,重写数组的操作方法
数组对象的操作
Proxy是非侵入的方法监管了对象的读写

const observe = (data, callback) => {
  return new Proxy(data, {
    get(target, key) {
      console.log('get:',target, key)
      return Reflect.get(target, key)
    },
    set(target, key, value, proxy) {
      console.log('set:',target, key,value,proxy)
      callback(key, value);
      target[key] = value;
      return Reflect.set(target, key, value, proxy)
    }
  })
}

const FooBar = { open: false,num:123 };
const FooBarObserver = observe(FooBar, (property, value) => {
  console.log(property, value)// callback(key, value);
  property === 'open' && value
    ? console.log('FooBar is open!!!')
    : console.log('keep waiting');
});
console.log(FooBarObserver.open) // false
FooBarObserver.open = true // FooBar is open!!!
上一篇下一篇

猜你喜欢

热点阅读