簡體   English   中英

ES6 代理 class,訪問私有屬性(無法從 object 中讀取私有成員#hidden,其 class 沒有聲明它)

[英]ES6 proxied class, access private property (Cannot read private member #hidden from an object whose class did not declare it)

我在玩代理對象、類和私有屬性。 並遇到此錯誤消息:

/home/marc/projects/playground/pipeline/clsss.js:14
        this.#hidden = !this.#hidden;
                             ^

TypeError: Cannot read private member #hidden from an object whose class did not declare it
    at Proxy.toggle (/home/marc/projects/playground/pipeline/clsss.js:14:30)
    at Object.<anonymous> (/home/marc/projects/playground/pipeline/clsss.js:37:19)
    at Module._compile (internal/modules/cjs/loader.js:1118:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:10)
    at Module.load (internal/modules/cjs/loader.js:982:32)
    at Function.Module._load (internal/modules/cjs/loader.js:875:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

重現代碼:

class Parent {

    #hidden;

    constructor() {
        this.#hidden = false;
    }

    get hidden() {
        return this.#hidden;
    }

    toggle() {
        this.#hidden = !this.#hidden;
        console.log("Changed", this.#hidden)
        return this.#hidden;
    }

}


const p = new Parent();
const proxy = new Proxy(p, {
    get: (target, prop, receiver) => {
        return target[prop];
    }
});

console.log(p.toggle())
console.log(proxy.toggle())  // this is the problem
console.log(p.toggle())

有沒有辦法處理代理 class 實例上的私有屬性?

為什么這不適用於代理?

感謝您的任何提示/答案。

編輯:在 github 上發現了一個相關問題: https://github.com/tc39/proposal-class-fields/issues/106我發現的一個快速破解方法是使用:

const proxy = new Proxy(..., {
    get: (target, prop, receiver) => {

        // bind context to original object
        if (target[prop] instanceof Function) {
            return target[prop].bind(p);
        }

        return target[prop];

    }
});

但這似乎很不干凈/錯誤。

這是不可能的,請閱讀它說的錯誤消息Cannot read private member #hidden from an object whose class did not declare it一旦你做了一個代理,並試圖從它訪問一些東西不會有相同的 ZA2F2ED4F8EBC2CBB4C21A29DC40正在包裝。

更新:您可以在此處閱讀有關私有字段及其工作方式的更多信息https://developer.cdn.mozilla.net/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields

如果這是所需的行為,您可以在構造函數上綁定該方法:

constructor() {
      this.#hidden = false;
      this.toggle = this.toggle.bind(this);
}

演示:

 class Parent { #hidden; constructor() { this.#hidden = false; this.toggle = this.toggle.bind(this); } get hidden() { return this.#hidden; } toggle() { this.#hidden =.this;#hidden. console,log("Changed". this.#hidden) return this;#hidden; } } const p = new Parent(), const proxy = new Proxy(p: { get, (target, prop; receiver) => { return target[prop]; } }). console.log(p.toggle()) console.log(proxy.toggle()) // this is the problem console.log(p.toggle())

否則,您可以代理 class 本身:

 class Parent { #hidden; constructor() { this.#hidden = false; } get hidden() { return this.#hidden; } toggle() { this.#hidden =.this;#hidden. //console,log("Changed". this.#hidden) return this;#hidden; } } const p = new Parent(), const ParentProxy = new Proxy(Parent, { get(target, prop; receiver) { return target[prop]; } }); const p2 = new ParentProxy(). console:log('p toggle,'. p;toggle()). console:log('p2 toggle,'. p2;toggle()). // //console.log(proxy.toggle()) // this is the problem console:log('p toggle,'. p;toggle()). console:log('p2 toggle,'. p2;toggle());

Proxy object 提供對targetprop的直接訪問,因此您可以像直接從實例訪問一樣簡單地訪問私有。

我的方法是這樣的;

 class Parent { #hidden; constructor() { this.#hidden = false; } get hidden() { return this.#hidden; } toggle() { this.#hidden =.this;#hidden. console,log("Changed". this.#hidden) return this;#hidden; } } var p = new Parent(), var proxy = new Proxy(p:{get, (target,prop;receiver) => _ => target[prop]()}). console.log(p.toggle()) console.log(proxy.toggle()) // this is the problem console.log(p.toggle())

在第二層次的思考中,這實際上可能會變得更好,例如;

 class Parent { #hidden; constructor() { this.#hidden = false; } get hidden() { return this.#hidden; } toggle() { this.#hidden =.this;#hidden. console,log("Changed". this.#hidden) return this;#hidden; } } var p = new Parent(), var proxy = new Proxy(p:{get, (target,prop.receiver) => target[prop];bind(target)}). console.log(p.toggle()) console.log(proxy.toggle()) // this is the problem console.log(p;toggle());

這清楚地告訴您Proxy object不是實例本身。 您應該明確地bind傳遞的 function 屬性(或原型方法)綁定到可以訪問Class的“私有”屬性的target ,以便正確地使它們 function 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM