如何使用proxy,如何在内部拦截get方法

class A {
    constructor() {
        this.pc = {};
        this.pc.name = 123;
        setTimeout(() => {
            console.log(this.pc);//为什么这里不能触发 get 如何触发
        }, 1000)
    }
}
A = new Proxy(A, {
    get: (target, prop, recevier) => {
        console.log(target[prop]);//
        return target[prop];
    },
})
new A();

其实我的需求是
在多个class类里面 我用到了同一个 pc对象
但是有很多行代码 我都判断了 if(!this.pc){return onerror()}
我想这样做一个拦截判断 如果没有 this.pc 做对应的逻辑

对代码进行更改后 如何做到 在A B类中同时能拦截

class A {
            constructor() {
                this.pc = {};
                this.pc.name = 123;
                setTimeout(() => {
                    this.pc
                }, 1000)
                let obj = new Proxy(this, {
                    get: (target, prop, recevier) => {
                        console.log(target[prop]); // 如何做到 A B同时能拦截
                        return target[prop];
                    },
                })
                return obj
            }
        }
        class B extends A {
            constructor() {
                super()
                setTimeout(() => {
                    this.pc
                }, 3000)
            }
        }

        new B();
阅读 187
评论
    3 个回答
    • 11.4k
    1. Proxy 是类,new Proxy() 之后获得实例,实例不能再 new 一次。
    2. Proxy 会代理对 对象 的访问,所以你只能拦截 对象(也就是实例)的 get,而不是类的 get,所以你只能 new Proxy(实例),或者 new Proxy(new A())
    3. JS 的 class 声明其实是原型链的语法糖,它的使用也跟以前的 new func() 很接近。class 声明的类必须有 constructor 作为构造函数,这个构造函数不仅包含实例的初始化,还可以 return 一个值,如果这个值是一个对象的话,这个对象会代替实例返回给 new 语句。
    4. 所以,如果你想获得一个类的实例的代理,可以这样做:

      class A {}
      
      class ProxyA extend A {
        constructor() {
          super();
          
          return new Proxy(this, {
            get(target, property) {
              if (property === '你想拦截的,比如 foo') {
                return 'hello world';
              }
              return target[property];
            }
          });
        }
      }
      
      const a = new ProxyA();
      a.foo(); // "hello world"