Dieser Artikel bietet Ihnen eine umfassende Analyse privater Mitglieder in js (mit Code). Ich hoffe, dass er für Freunde in Not hilfreich ist.
Klassenfelddeklarationen für JavaScript (Felddeklarationen von JavaScript-Klassen) sind jetzt in Stufe 3 eingetreten, die ein Element enthält, das OOP-Entwicklern große Sorgen bereitet: Private Felder. Nicht umsonst hatte JavaScript nie private Mitglieder, daher bringt dieser Vorschlag neue Herausforderungen für JavaScript mit sich. Gleichzeitig dachte JavaScript jedoch bereits bei der Veröffentlichung von ES2015 über die Frage der Privatisierung nach, sodass die Implementierung privater Mitglieder nicht ohne Grundlage ist.
Graben Sie zuerst eine Grube - das ist ein Teil des JS-Codes. BusinessView
muss zwei Dinge tun, nämlich das Layout des Formulars und die Karte.
class BaseView { layout() { console.log("BaseView Layout"); } } class BusinessView extends BaseView { layout() { super.layout(); this._layoutForm(); this._layoutMap(); } _layoutForm() { // .... } _layoutMap() { // .... } }
Dann wurde aufgrund der Geschäftsentwicklung festgestellt, dass viele Ansichten Kartenlayouts haben. Zur Implementierung wird hier die Vererbungsmethode verwendet, sodass der kartenbezogene Inhalt von BusinessView
in eine Basisklasse namens MapView
abstrahiert wird:
class MapView extends BaseView { layout() { super.layout(); this._layoutMap(); } _layoutMap() { console.log("MapView layout map"); } } class BusinessView extends MapView { layout() { super.layout(); this._layoutForm(); this._layoutMap(); } _layoutForm() { // .... } _layoutMap() { console.log("BusinessView layout map"); } }
Die beiden oben genannten Codeteile basieren auf sehr typischen OOP-Ideen Bei der Vererbung besteht die ursprüngliche Absicht darin, zu erwarten, dass Klassen auf jeder Ebene layout()
verwenden können, um Layoutaufgaben auszuführen, für die jede Ebene verantwortlich sein sollte. Aber es gibt immer eine Lücke zwischen Ideal und Realität. Wenn Sie es in JavaScript ausführen, werden Sie feststellen, dass BusinessView._layoutMap()
zweimal ausgeführt wird, während MapView._layoutMap()
nicht ausgeführt wird. Warum?
Wenn in JavaScript eine Methode mit demselben Namen in der Vorfahren- und Nachkommenklasse definiert ist, wird diese Methode in der Nachkommenklasse standardmäßig aufgerufen. Wenn Sie die gleichnamige Methode in der Vorfahrenklasse aufrufen möchten, müssen Sie sie über super.
in der Nachkommenklasse aufrufen.
Hier können Sie diesen Prozess analysieren:
Wenn eine Unterklasse ein Objekt erstellt, wurden die Definitionen ihrer Klasse und aller Vorgängerklassen geladen. Zu diesem Zeitpunkt ruft
BusinessView.layout()
auf, um super.layout()
zu finden und MapView.layout()
MapView.layout()
this._layoutMap()
BusinessView
_layoutMap()
Objekt) > Finden Sie es und nennen Sie es
BusinessView
_layoutMap
BusinessView.layout()
base.layout()
MapView.layout()
MapView.layout()
this._layoutMap()
MapView 🎜>_layoutMap()
Überprüfen Sie, ob die virtuelle Funktion funktioniert
aufrufen, wenn
als privat definiert ist._layoutMap
Das Konzept der virtuellen Funktionen ist etwas kompliziert. Es kann jedoch einfach verstanden werden, dass eine Mitgliedsmethode, wenn sie als virtuelle Funktion deklariert wird, beim Aufruf ihrer virtuellen Funktionskette folgt, um die letzte aufzurufende Überladung zu finden. MapView.layout()
MapView._layoutMap()
Obwohl das
eine private Methode ist und die Definition in dieser Klasse aufrufen sollte, anstatt in der Unterklasse nach der Definition zu suchen.
Lösen Sie das aktuelle Privatisierungsproblem_
_layoutMap()
JavaScript hat derzeit keine privaten Mitglieder, aber wir müssen das Problem der privaten Mitglieder schnell und effektiv lösen. Was sollen wir tun? Natürlich gibt es eine Möglichkeit, das Problem zu lösen, indem man
Symbol
Zunächst möchten wir klarstellen, dass wir uns mit diesem Privatisierungsproblem in einem befassen werden Flexibler Weg - das heißt, lassen Sie die Vorfahren Wenn ein Klassenaufrufer eine Methode aufruft, sucht er nicht zuerst in der Unterklasse. Dieses Problem kann grammatikalisch nicht gelöst werden. JavaScript muss nach der Methode suchen, den Namen von der spezifischen Instanz aus rückwärts anzugeben. Was aber, wenn der Methodenname nicht gefunden werden kann?
之所以能找到,因为方法名是字符串。一个字符串在全局作用域内都表示着同样的意义。但是 ES2015 带来了 Symbol
,它必须实例化,而且每次实例化出来一定代表着不同的标识 —— 如果我们将类定义在一个闭包中,在这个闭包中声明一个 Symbol
,用它来作为私有成员的名称,问题就解决了,比如
const MapView = (() => { const _layoutMap = Symbol(); return class MapView extends BaseView { layout() { super.layout(); this[_layoutMap](); } [_layoutMap]() { console.log("MapView layout map"); } } })(); const BusinessView = (() => { const _layoutForm = Symbol(); const _layoutMap = Symbol(); return class BusinessView extends MapView { layout() { super.layout(); this[_layoutForm](); this[_layoutMap](); } [_layoutForm]() { // .... } [_layoutMap]() { console.log("BusinessView layout map"); } } })();
而现代基于模块的定义,甚至连闭包都可以省了(模块系统会自动封闭作用域)
const _layoutMap = Symbol(); export class MapView extends BaseView { layout() { super.layout(); this[_layoutMap](); } [_layoutMap]() { console.log("MapView layout map"); } }
const _layoutForm = Symbol(); const _layoutMap = Symbol(); export class BusinessView extends MapView { layout() { super.layout(); this[_layoutForm](); this[_layoutMap](); } [_layoutForm]() { // .... } [_layoutMap]() { console.log("BusinessView layout map"); } }
改革过后的代码就可以按预期输出了:
BaseView Layout MapView layout map BusinessView layout map
相关推荐:
Das obige ist der detaillierte Inhalt vonUmfassende Analyse privater Mitglieder in js (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!