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

mikechen
  • 556
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();
回复
阅读 657
3 个回答
✓ 已被采纳
  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"

你这样给 A 加了个 proxy ,但是 new A() 出来的对象已经跟 A 没有太多关系了。

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

我也是前两天才看的proxy,但是不得不说你一下,那么多的变量你换一个多好。
代理是把功能代理给了一个新的对象,你把下面那个A=....换成B=...的就容易理解多了。
你上面那个this.pc,this指向的是当前class,而不是代理后的对象B,而A还是原来的功能,
所以不会执行。
如果在Class A中改成:

constructor() {
    setTimeout(() => {
        // 因为你是直接代理class A的get方法,所以这一步会直接走你写的get
        const pc = new B();
        // console.log(123);
    }, 1000);
}

就没事了

你知道吗?

宣传栏