簡體   English   中英

在ES6中,如何覆蓋超類中的私有方法?

[英]In ES6, how to override a private method in a super class?

我正在學習ES6中的課程......

我想以某種形式使用私有屬性,以便只能從類的實例調用某些方法。

例如使用Symbol ...

/* A.js */

const _privateMethod = Symbol('_privateMethod')
class A {
    [_privateMethod]() {
        return 'yup'
    }
    do() {
        return this[_privateMethod]()
    }
}

const a = new A()
a.do() /* yup */

..._ privateMethod無法直接調用。 到現在為止還挺好。

但是,我想知道如何在繼承自A的類中重寫_privateMethod。例如,以下內容將不起作用:

/* B.js */

const _privateMethod = Symbol('_privateMethod')
class B extends A {
    [_privateMethod]() {
        return 'nope'
    }
}

const b = new B()
b.do() /* yup */

怎么建議這樣做?

調用Symbol('_privateMethod')再次創建一個新的,不同的符號(即使它具有相同的描述)。 您正在使用不同的密鑰創建不同的方法,而不是覆蓋原始密鑰。

您將需要使用完全相同符號來定義子類中的方法。 您可以從Object.getOwnPropertySymbols(A.prototype)獲取它,也可以從Object.getOwnPropertySymbols(A.prototype)導出_privatMethod符號作為常量並將其導入B.js(與class A一起)。 但是,如果你想使類可擴展,我建議根本不使用符號。

編程概念在實踐中使用的原因是它們為開發人員提供了一些好處,這也包括封裝。 如果它提供的缺點多於好處,這意味着它不應該應用,或者它的應用方式是錯誤的。

JavaScript沒有提供封裝作為語言功能。 符號是一種可接受的實現方式,但它的特殊性使其不適合執行任務。

作為私有(受保護)成員的標識符的符號應始終與其所屬的類一起導出:

export const _privateMethod = Symbol('_privateMethod');
export class A {
    [_privateMethod]() {/*...*/}
    /*...*/
}

...

import { _privateMethod, A } from './a';

class B extends A {
    [_privateMethod]() {/*...*/}
}

如果這不可能或不實用,這意味着符號是封裝的不恰當選擇,因為它提供了缺點而沒有任何實際好處。

由於信息隱藏在JavaScript中不能提供安全性(符號可以通過Object.getOwnPropertySymbols訪問),因此封裝機制的替代方法是使用匈牙利表示法和/或JSDoc注釋。 它們為開發人員提供有關公共接口的必要信息:

export class A {
    /** @protected */
    _privateMethod() {/*...*/}
    /*...*/
}

您可以使用Object.getOwnPropertySymbols()函數:

 const A = (function() { const _privateMethod = Symbol('_privateMethod') return class A { [_privateMethod]() { return 'yup' } do() { return this[_privateMethod]() } } }()); (function() { const _privateMethod = Object.getOwnPropertySymbols(A.prototype) .find(x => x.toString() === 'Symbol(_privateMethod)') class B extends A { [_privateMethod]() { return 'nope' } } const b = new B() console.log(b.do()); }()); 

你已經有了正確的答案,請檢查一下

 const _privateMethod = Symbol('_privateMethod') class A { [_privateMethod]() { return 'yup' } do() { return this[_privateMethod]() } } const a = new A() document.write(a.do()+ "<br><br>" ) class B extends A { [_privateMethod]() { return 'nope' } } const b = new B() document.write(b.do()+ "<br><br>") 

暫無
暫無

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

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