Maison >interface Web >js tutoriel >Les nouveaux champs de classe privée de JavaScript, et comment les utiliser
ES6 présente des classes pour JavaScript, mais pour des applications complexes, elles peuvent être trop simples. Les champs de classe (également appelés attribut de classe ) sont conçus pour simplifier les constructeurs avec des membres privés et statiques. La proposition est actuellement dans le stade TC39 Phase 3: candidat et sera probablement ajoutée à ES2019 (ES10). Node.js 12, Chrome 74 et Babel prennent actuellement en charge les champs privés. Avant de comprendre comment les champs de classe sont mis en œuvre, il est utile de revoir la classe ES6. Cet article a été mis à jour en 2020. Pour des connaissances JavaScript plus approfondies, lisez notre livre "JavaScript: From Newbie to Ninja, deuxième édition".
Points clés
ES6 Basics de catégorie
Les développeurs de langues tels que C, C #, Java et PHP peuvent être confus par le modèle d'héritage orienté objet de JavaScript. Par conséquent, ES6 a introduit la classe . Ils sont principalement du sucre syntaxique, mais offrent un concept plus familier de programmation orientée objet. Une classe est un modèle d'objet qui définit comment les objets de ce type se comportent. La classe animale suivante définit les animaux généraux (les classes sont généralement représentées en majuscules initiaux pour les distinguer des objets et d'autres types):
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } speak() { console.log(`${this.name} says "${this.noise}"`); } walk() { console.log(`${this.name} walks on ${this.legs} legs`); } }</code>
Les déclarations de classe sont toujours exécutées en mode strict. Pas besoin d'ajouter «Utiliser Strict». La méthode du constructeur s'exécute lors de la création d'un objet de type animal. Il définit généralement les propriétés initiales et gère d'autres initialisations. Speak () et Walk () sont des méthodes d'instance qui ajoutent plus de fonctionnalités. Vous pouvez maintenant utiliser le nouveau mot clé pour créer des objets à partir de cette classe:
<code class="language-javascript">let rex = new Animal('Rex', 4, 'woof'); rex.speak(); // Rex says "woof" rex.noise = 'growl'; rex.speak(); // Rex says "growl"</code>
getter et seter
setter est une méthode spéciale utilisée uniquement pour définir les valeurs. De même, Getter est une méthode spéciale pour les valeurs de retour uniquement. Par exemple:
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } speak() { console.log(`${this.name} says "${this.noise}"`); } walk() { console.log(`${this.name} walks on ${this.legs} legs`); } // setter set eats(food) { this.food = food; } // getter get dinner() { return `${this.name} eats ${this.food || 'nothing'} for dinner.`; } } let rex = new Animal('Rex', 4, 'woof'); rex.eats = 'anything'; console.log( rex.dinner ); // Rex eats anything for dinner.</code>
Sous-classe ou sous-classe
Il est généralement possible d'utiliser une classe comme classe de base pour une autre. La classe humaine peut hériter de toutes les propriétés et méthodes de la classe animale en utilisant le mot clé EXTENSE. Des propriétés et des méthodes peuvent être ajoutées, supprimées ou modifiées au besoin pour créer des objets humains plus faciles et plus clairs:
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } speak() { console.log(`${this.name} says "${this.noise}"`); } walk() { console.log(`${this.name} walks on ${this.legs} legs`); } }</code>
Super fait référence à la classe parent, c'est donc généralement le premier appel appelé dans le constructeur. Dans cet exemple, la méthode Human Speak () remplace la méthode définie dans l'animal. Vous pouvez maintenant créer une instance d'objet humain:
<code class="language-javascript">let rex = new Animal('Rex', 4, 'woof'); rex.speak(); // Rex says "woof" rex.noise = 'growl'; rex.speak(); // Rex says "growl"</code>
Méthodes et propriétés statiques
La définition de méthodes utilisant des mots clés statiques permet de l'appeler sur une classe sans créer une instance d'objet. Considérez les constantes math.pi: il n'est pas nécessaire de créer un objet mathématique avant d'accéder aux propriétés PI. ES6 ne prend pas en charge les mêmes propriétés statiques que les autres langues, mais les propriétés peuvent être ajoutées à la définition de classe elle-même. Par exemple, la classe humaine peut être adaptée pour maintenir le nombre d'objets humains créés:
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } speak() { console.log(`${this.name} says "${this.noise}"`); } walk() { console.log(`${this.name} walks on ${this.legs} legs`); } // setter set eats(food) { this.food = food; } // getter get dinner() { return `${this.name} eats ${this.food || 'nothing'} for dinner.`; } } let rex = new Animal('Rex', 4, 'woof'); rex.eats = 'anything'; console.log( rex.dinner ); // Rex eats anything for dinner.</code>Le Getter statique de la classe
renverra le nombre d'humains en conséquence:
<code class="language-javascript">class Human extends Animal { constructor(name) { // 调用Animal构造函数 super(name, 2, 'nothing of interest'); this.type = 'human'; } // 重写Animal.speak speak(to) { super.speak(); if (to) console.log(`to ${to}`); } }</code>
ES2019 Fields de classe ( new )
La nouvelle implémentation du champ de classe permet l'initialisation des propriétés publiques en dehors de tout constructeur en haut de la classe:
<code class="language-javascript">let don = new Human('Don'); don.speak('anyone'); // Don says "nothing of interest" to anyone don.eats = 'burgers'; console.log( don.dinner ); // Don eats burgers for dinner.</code>
Cela équivaut à:
<code class="language-javascript">class Human extends Animal { constructor(name) { // 调用Animal构造函数 super(name, 2, 'nothing of interest'); this.type = 'human'; // 更新Human对象的计数 Human.count++; } // 重写Animal.speak speak(to) { super.speak(); if (to) console.log(`to ${to}`); } // 返回人类对象的个数 static get COUNT() { return Human.count; } } // 类的静态属性本身 - 不是其对象 Human.count = 0;</code>
Si vous avez toujours besoin du constructeur, l'initialisateur sera exécuté avant son exécution.
Dans l'exemple ci-dessus, des propriétés statiques sont ajoutées à l'objet de définition de classe de manière inélégante après avoir défini l'objet de classe. Vous n'avez pas besoin d'utiliser des champs de classe:
<code class="language-javascript">console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 0 let don = new Human('Don'); console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 1 let kim = new Human('Kim'); console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 2</code>
Cela équivaut à:
<code class="language-javascript">class MyClass { a = 1; b = 2; c = 3; }</code>
ES6 sont publics par défaut et peuvent être vérifiés ou modifiés en dehors de la classe . Dans l'exemple d'animal ci-dessus, rien ne peut empêcher de modifier la propriété alimentaire sans appeler le setter à manger:
<code class="language-javascript">class MyClass { constructor() { this.a = 1; this.b = 2; this.c = 3; } }</code>D'autres langues permettent généralement la déclaration d'attributs privés. Ce n'est pas possible dans ES6, donc les développeurs utilisent souvent des conventions de soulignement (_propertyName), des fermetures, des symboles ou des maps faibles pour résoudre ce problème. Le soulignement donne aux développeurs un indice, mais rien ne peut les empêcher d'accéder à la propriété. Dans ES2019, les champs de classe privée sont définis à l'aide de Hash # Prefix:
<code class="language-javascript">class MyClass { x = 1; y = 2; static z = 3; } console.log( MyClass.z ); // 3</code>Veuillez noter que les méthodes privées, les getters ou les setters ne peuvent pas être définis. TC39 Phase 3: Draft Proposition recommande l'utilisation d'un préfixe de hachage # pour les noms, qui est implémenté dans Babel. Par exemple:
<code class="language-javascript">class MyClass { constructor() { this.x = 1; this.y = 2; } } MyClass.z = 3; console.log( MyClass.z ); // 3</code>
Bénéfice immédiatement: Code de réaction plus concis!
Les composants réagis ont généralement des méthodes liées aux événements DOM. Pour s'assurer que cela se résout en composant, il est nécessaire de lier chaque méthode en conséquence. Par exemple:
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } set eats(food) { this.food = food; } get dinner() { return `${this.name} eats ${this.food || 'nothing'} for dinner.`; } } let rex = new Animal('Rex', 4, 'woof'); rex.eats = 'anything'; // 标准setter rex.food = 'tofu'; // 完全绕过eats setter console.log( rex.dinner ); // Rex eats tofu for dinner.</code>Lorsqu'il est défini comme un champ de classe ES2019, il peut être attribué en fonction à l'aide de la flèche ES6 = & gt; qui est automatiquement liée à l'objet de définition. Pas besoin d'ajouter une instruction de liaison:
<code class="language-javascript">class MyClass { a = 1; // .a是公共的 #b = 2; // .#b是私有的 static #c = 3; // .#c是私有的和静态的 incB() { this.#b++; } } let m = new MyClass(); m.incB(); // 运行正常 m.#b = 0; // 错误 - 私有属性不能在类外部修改</code>
Champ de classe: amélioré?
La définition de la classe ES6 est trop simple. Les champs de classe ES2019 nécessitent moins de code, améliorent la lisibilité et implémentent certaines possibilités intéressantes pour la programmation orientée objet. Utiliser # signifie la privatin a reçu des critiques, principalement parce qu'elle est laide et ressemble à une compétence. La plupart des langues implémentent le mot-clé privé, donc essayer d'utiliser ce membre en dehors de la classe sera rejeté par le compilateur. JavaScript est interprété. Considérez le code suivant:
<code class="language-javascript">class Animal { constructor(name = 'anonymous', legs = 4, noise = 'nothing') { this.type = 'animal'; this.name = name; this.legs = legs; this.noise = noise; } speak() { console.log(`${this.name} says "${this.noise}"`); } walk() { console.log(`${this.name} walks on ${this.legs} legs`); } }</code>
Cela lancera une erreur d'exécution sur la dernière ligne, mais ce n'est qu'une grave conséquence d'essayer de définir la propriété. JavaScript est délibérément tolérant et ES5 permet de modifier les propriétés sur n'importe quel objet. Bien que maladroit, le symbole # est invalide en dehors de la définition de la classe. Essayer d'accéder à MyObject. # Secret peut lancer une erreur de syntaxe. Ce débat se poursuivra, mais les champs de classe sont déjà adoptés dans plusieurs moteurs JavaScript, comme cela. Ils continueront d'exister.
FAQS (FAQ) sur les champs de classe privée JavaScript
Les champs de classe privée en JavaScript fournissent un moyen d'encapsuler ou de masquer des données dans une classe, qui est le principe de base de la programmation orientée objet. Cette encapsulation garantit que l'état interne d'un objet ne peut être modifié que par une classe explicitement définie. Cela rend le code plus robuste et prévisible car il empêche le code externe de modifier accidentellement l'état de l'objet d'une manière inattendue. De plus, les champs privés peuvent aider à simplifier l'interface des classes car elles réduisent le nombre de propriétés et de méthodes exposées au monde extérieur.
Dans JavaScript, les champs de classe privée sont déclarés en ajoutant un symbole de hachage (#) avant le nom du champ. Par exemple, pour déclarer un champ privé nommé "valeur" dans une classe, vous pouvez écrire un #Value. Ce champ ne peut ensuite être accessible que dans les méthodes internes de la classe, et non de l'extérieur de la classe.
Non, les champs de classe privée en JavaScript ne sont pas accessibles à partir de l'extérieur de la classe. C'est par conception, car l'une des principales utilisations des champs privés est de masquer les données internes du monde extérieur. Si vous essayez d'accéder à un champ privé depuis l'extérieur de la classe, JavaScript lancera une erreur de syntaxe.
Oui, les classes JavaScript peuvent avoir des domaines privés et publics. Les domaines publics sont déclarés de la même manière que les champs privés, mais n'ont pas de préfixe de hachage (#). Contrairement aux champs privés qui ne sont accessibles qu'à l'intérieur d'une classe, les champs publics sont accessibles et modifiés à l'intérieur et à l'extérieur de la classe.
Les champs de classe privée et les méthodes privées en JavaScript ont des utilisations similaires, qui fournissent tous deux un moyen de masquer les détails internes d'une classe du monde extérieur. Cependant, ils sont utilisés différemment. Les champs privés sont utilisés pour stocker des données qui ne peuvent être accessibles que dans la classe, tandis que les méthodes privées sont des fonctions qui ne peuvent être appelées qu'à l'intérieur de la classe.
Les champs de classe privée sont des fonctionnalités relativement nouvelles en JavaScript, donc tous les environnements ne le prennent pas en charge. Au moment de la rédaction du moment de la rédaction, les dernières versions de la plupart des navigateurs majeurs, notamment Chrome, Firefox et Safari, prennent en charge les champs privés. Cependant, Internet Explorer ne les soutient pas. Si vous devez écrire du code qui s'exécute dans tous les navigateurs, vous devrez peut-être utiliser un convertisseur comme Babel pour convertir le code en un formulaire que les navigateurs plus anciens peuvent comprendre.
Pour utiliser un champ de classe privée dans une méthode interne d'une classe, reportez-vous simplement au champ avec son nom (préfixé avec un symbole de hachage (#)). Par exemple, si vous avez un champ privé appelé "valeur", vous pouvez y accéder dans votre méthode comme ceci: ce. # Valeur.
Oui, les champs de classe privée peuvent être utilisés dans les sous-classes de JavaScript. Cependant, chaque sous-classe a son propre ensemble indépendant de champs privés qui ne sont pas partagés avec des superclasses ou d'autres sous-classes. Cela signifie que si le champ privé déclaré par la sous-classe est du même nom que le champ privé de la superclasse, les deux champs sont complètement indépendants et n'interfèrent pas les uns avec les autres.
Non, les champs de classe privée en JavaScript ne peuvent pas être utilisés dans les méthodes statiques. En effet, les méthodes statiques sont associées à la classe elle-même, et non aux instances de la classe, et les champs privés ne sont accessibles que dans les cas de la classe.
Non, les champs de classe privée en JavaScript ne sont pas inclus dans l'itération de la propriété de l'objet. C'est par conception, car l'une des principales utilisations des champs privés est de masquer les données internes du monde extérieur. Si vous avez besoin d'itérer les propriétés de l'objet, vous devez utiliser un champ ou une méthode public à la place.
Cette réponse maintient le format d'image d'origine et le placement, et paraphrase le texte tout en préservant la signification d'origine.
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!