Ce que cet article vous apporte, c'est une analyse complète des membres privés en js (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Les déclarations de champs de classe pour JavaScript (déclarations de champs des classes JavaScript) sont maintenant entrées dans l'étape 3, qui comprend un élément qui préoccupe beaucoup les développeurs POO : les champs privés. Ce n’est pas pour rien que JavaScript n’a jamais eu de membres privés, cette proposition apporte donc de nouveaux défis à JavaScript. Mais en même temps, JavaScript envisageait déjà la question de la privatisation lors de la sortie d'ES2015, il n'est donc pas sans fondement pour implémenter des membres privés.
Creusez d'abord une fosse - il s'agit d'un morceau de code JS, BusinessView
doit faire deux choses, à savoir disposer le formulaire et la carte.
class BaseView { layout() { console.log("BaseView Layout"); } } class BusinessView extends BaseView { layout() { super.layout(); this._layoutForm(); this._layoutMap(); } _layoutForm() { // .... } _layoutMap() { // .... } }
Ensuite, en raison du développement de l'entreprise, il a été découvert que de nombreuses vues avaient des mises en page cartographiques. La méthode d'héritage est utilisée ici pour l'implémenter, de sorte que le contenu lié à la carte est extrait de BusinessView
dans une classe de base appelée MapView
:
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"); } }
Les deux morceaux de code ci-dessus sont très typiques basés sur sur l'héritage. L'intention initiale de la POO est de s'attendre à ce que les classes de tous les niveaux puissent utiliser layout()
pour effectuer des tâches de mise en page dont chaque niveau devrait être responsable. Mais il y a toujours un écart entre l'idéal et la réalité. Si vous l'exécutez en JavaScript, vous constaterez que BusinessView._layoutMap()
est exécuté deux fois, tandis que MapView._layoutMap()
ne l'est pas. Pourquoi ?
En JavaScript, si une méthode du même nom est définie dans les classes ancêtre et descendante, cette méthode dans la classe descendante sera appelée par défaut. Si vous souhaitez appeler la méthode du même nom dans la classe ancêtre, vous devez l'appeler via super.
dans la classe descendante.
Ici vous pouvez analyser ce processus :
Lorsqu'une sous-classe crée un objet, les définitions de sa classe et de toutes les classes ancêtres ont été chargées. À ce moment-là,
appelle BusinessView.layout()
pour trouver super.layout()
et commencer à appeler MapView.layout()
MapView.layout()
this._layoutMap()
BusinessView
_layoutMap()
, la chaîne prototype n'est pas du tout recherchée. Oui, il s'agit d'une limitation de la POO basée sur des relations prototypes. Si nous regardons le processus de traitement de C#, nous constaterons qu'il est différent BusinessView
_layoutMap
BusinessView.layout()
base.layout()
MapView.layout()
MapView.layout()
this._layoutMap()
MapView
_layoutMap() 🎜>
est défini comme privé, alors
doit appeler. _layoutMap
MapView.layout()
Le concept de fonctions virtuelles est un peu compliqué. Cependant, on peut simplement comprendre que si une méthode membre est déclarée comme fonction virtuelle, lorsqu'elle est appelée, elle suivra sa chaîne de fonctions virtuelles pour trouver la dernière surcharge à appeler. MapView._layoutMap()
soit convenu comme étant privé en JavaScript, il ne s'agit que d'un gentleman's Agreement, et il n'est toujours pas de nature privée. Un gentleman's Agreement est valable pour les personnes, mais l'ordinateur ne sait pas que vous avez cet accord... Cependant, si JavaScript implémente réellement des membres privés, alors l'ordinateur saura queest une méthode privée et devra appeler la définition dans cette classe au lieu de rechercher la définition dans la sous-classe.
_
Résoudre le problème actuel de la privatisation_layoutMap()
Notez que la fermeture ici n'est pas un guide pour générer une fermeture dans une fonction, veuillez continuer la lecture Symbol
之所以能找到,因为方法名是字符串。一个字符串在全局作用域内都表示着同样的意义。但是 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"); } } })();Copier après la connexion而现代基于模块的定义,甚至连闭包都可以省了(模块系统会自动封闭作用域)
const _layoutMap = Symbol(); export class MapView extends BaseView { layout() { super.layout(); this[_layoutMap](); } [_layoutMap]() { console.log("MapView layout map"); } }Copier après la connexionconst _layoutForm = Symbol(); const _layoutMap = Symbol(); export class BusinessView extends MapView { layout() { super.layout(); this[_layoutForm](); this[_layoutMap](); } [_layoutForm]() { // .... } [_layoutMap]() { console.log("BusinessView layout map"); } }Copier après la connexion改革过后的代码就可以按预期输出了:
BaseView Layout MapView layout map BusinessView layout mapCopier après la connexion相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!