[英]ES6 proxied class, access private property (Cannot read private member #hidden from an object whose class did not declare it)
[英]Cannot read private member from an object whose class did not declare it...?
在這個程序中:
class Example { #privateMember = 123; // these are fine addNumber (n) { return this.#privateMember + n; } doAddNumber (n) { return this.addNumber(n); } // "cannot read private member #privateMember from an // object whose class did not declare it" #operations = { add: this.addNumber }; operate (n) { return this.#operations.add(n); } } const ex = new Example(); console.log(ex.addNumber(77)); console.log(ex.doAddNumber(77)); console.log(ex.operate(77));
調用addNumber
可以正常工作, doAddNumber
也可以,但是調用operate
會產生錯誤:
TypeError: Cannot read private member #privateMember from an object whose class did not declare it
at Object.addNumber [as add] (<anonymous>:11:17)
at Example.operate (<anonymous>:20:29)
at <anonymous>:27:16
at dn (<anonymous>:16:5449)
我無法理解這個錯誤,因為:
addNumber
工作正常,所以它至少不是語法錯誤或拼寫錯誤。doAddNumber
工作正常,因此從其他函數調用函數不是問題。operate
只是調用addNumber
,從 (1) 開始,它工作正常。this
是一個 object,它的 class 聲明#privateMember
...我的意思是, this
是一個Example
,我可以看到它是在Example
中聲明的。 就在那里……我自己打的……我發現TypeError: Cannot read private member from an object whose class didn't declare it但我不明白它是如何應用的,如果它適用。
我不知道這里發生了什么。 為什么即使addNumber
和doAddNumber
, operate
也不起作用?
在我的真實代碼中(這只是一個最小的例子),我正在嘗試使用像#operations
這樣的字典來保存許多用於執行任務的各種算法的實現,由字符串 ID 索引,其中指定了字符串算法 ID給構造函數。 這也很方便,因為我可以從此字典中獲取鍵以提供有效算法 ID 的列表,而無需在任何地方復制該列表。 現在,我可以將它切換到if
語句並確保我也使可查詢列表保持最新,但我不明白為什么這不起作用。
當您設置#operations.addNumber
然后調用它時, this === #operations
而非ex
會失敗,因為ex.#operarions.#privateMember
不存在。
如果我將您的Example
class 更改為
#operations = { add: this.addNumber.bind(this)};
然后ex.#operations.add
使用this === ex
運行,你的代碼返回
> 200
> 200
> 200
這是我相信您所追求的工作示例...
class Example { #privateMember = 123; // these are fine addNumber (n) { return this.#privateMember + n; } doAddNumber (n) { return this.addNumber(n); } // "cannot read private member #privateMember from an // object whose class did not declare it" #operations = { add: this.addNumber }; operate (n) { return this.#operations.add.call(this, n); } } const ex = new Example(); console.log(ex.addNumber(77)); console.log(ex.doAddNumber(77)); console.log(ex.operate(77));
簡而言之,在您的代碼中,#operations 方法只是創建一個 object,並引用 addNumber 的示例 class 方法,與任何 object 沒有關聯。因此,當嘗試使用此引用時,您需要傳遞一個 object ...
也就是說,你本質上是在定義......
#operations = { add: Example.prototype.addNumber }
在建議的解決方案中, operate
方法在#operations object 中調用對addNumber
方法的引用,但當然必須將 object 傳遞給addNumber
,並通過執行call( this, ...)
實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.