Maison >interface Web >js tutoriel >Résumé de l'implémentation des variables privées dans ES6 (exemple de code)
Cet article vous apporte un résumé de l'implémentation des variables privées dans ES6 (exemples de code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
En lisant "Introduction à ECMAScript 6", j'ai vu des implémentations dispersées de variables privées, je vais donc les résumer ici.
class Example { constructor() { this._private = 'private'; } getName() { return this._private } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // private
Méthode d'écriture simple
Facile à déboguer
Bonne compatibilité
Les externes peuvent accéder et modifier
Le langage n'a pas de mécanisme de correspondance. Par exemple, l'instruction for in énumérera tous les attributs
Conflit de noms
/** * 实现一 */ class Example { constructor() { var _private = ''; _private = 'private'; this.getName = function() {return _private} } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
Aucun conflit de noms
Les externes ne peuvent pas accéder et modifier
La logique du constructeur devient compliquée. Le constructeur ne doit effectuer que l'initialisation des objets. Désormais, pour implémenter des variables privées, il doit inclure l'implémentation de certaines méthodes, et l'organisation du code est légèrement floue.
Les méthodes existent sur les instances, pas sur les prototypes, et les sous-classes ne peuvent pas utiliser super pour appeler
La construction ajoute un peu de surcharge
/** * 实现二 */ const Example = (function() { var _private = ''; class Example { constructor() { _private = 'private'; } getName() { return _private; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
Aucun conflit de nom
Non accessible de l'extérieur Et modifications
La méthode d'écriture est un peu compliquée
La construction ajoute un peu frais généraux
const Example = (function() { var _private = Symbol('private'); class Example { constructor() { this[_private] = 'private'; } getName() { return this[_private]; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
Aucun conflit de nom
Impossible d'accéder et de modifier en externe
Aucune perte de performances
La méthode d'écriture est légèrement compliquée
La compatibilité est également bonne
/** * 实现一 */ const _private = new WeakMap(); class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
Si vous l'écrivez comme ceci, vous pourriez avoir l'impression que l'encapsulation n'est pas suffisante. Vous pouvez également l'écrire comme ceci :
/** * 实现二 */ const Example = (function() { var _private = new WeakMap(); // 私有成员存储容器 class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }Alors pourquoi ne pas utiliser directement les champs privés ? Par exemple :
class Foo { private value; equals(foo) { return this.value === foo.value; } }Pour faire simple, c'est gênant, et bien sûr il y a des considérations de performances... Par exemple, si nous n'utilisons pas #, mais utilisons private Mots-clés :
class Foo { private value = '1'; equals(foo) { return this.value === foo.value; } } var foo1 = new Foo(); var foo2 = new Foo(); console.log(foo1.equals(foo2));Ici, nous créons deux nouvelles instances, puis passons foo2 comme paramètre dans la méthode d'instance de foo1. Alors pouvons-nous obtenir la valeur de foo2.value ? Si nous
directement, nous ne pourrons certainement pas obtenir la valeur. Après tout, c'est une variable privée, mais equals est une méthode de classe de Foo, alors pouvons-nous l'obtenir ? foo2.value
Les fonctions membres d'une classe peuvent accéder aux variables privées des instances du même type C'est parce que la confidentialité l'est. pour l'implémentation, les informations "externes" sont cachées dans la classe elle-même. Il n'est pas nécessaire d'interdire l'accès aux variables privées. Vous pouvez également comprendre que les restrictions sur les variables privées sont basées sur la classe et non sur l'objet. offrir aux utilisateurs la commodité d’apporter.
Puisque l'obtention de la valeur est correcte, le résultat imprimé devrait être vrai, mais que se passe-t-il si la valeur que nous transmettons n'est pas une instance de Foo, mais un autre objet ?var foo1 = new Foo(); console.log(foo1.equals({ value: 2 }));Bien sûr, le code ici peut s'exécuter normalement, mais pour le compilateur, c'est un peu gênant, car le compilateur ne sait pas si la valeur est un attribut normal ou un attribut privé de foo, donc le compilateur Vous devez porter un jugement, juger d'abord si foo est une instance de Foo, puis obtenir la valeur. Cela signifie également qu'un tel jugement doit être fait pour chaque accès aux attributs, et le moteur a été hautement optimisé autour de l'accès aux attributs et est trop paresseux pour changer, et cela réduit également la vitesse. Mais en plus de ce travail, il y a d'autres choses à considérer, telles que :
et une nouvelle syntaxe de recherche de slot. Bref, elle sera plus simple que la méthode privée. méthode de mise en œuvre. private slots
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!