![](/img/trans.png)
[英]Is there any difference between WeakMap and private member of a class in JavaScript ES6?
[英]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 提供對target
和prop
的直接訪問,因此您可以像直接從實例訪問一樣簡單地訪問私有。
我的方法是這樣的;
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.