Maison  >  Article  >  interface Web  >  Exemple d'introduction au constructeur JavaScript et au nouvel opérateur

Exemple d'introduction au constructeur JavaScript et au nouvel opérateur

黄舟
黄舟original
2017-08-22 11:13:301059parcourir

Cet article présente principalement le constructeur JavaScript et le nouvel opérateur. Il présente de manière exhaustive les points de connaissance grâce à la compréhension du nouvel opérateur, de l'interprétation du code, de l'analyse des clés, de la signification du nouveau, du résumé, etc. Vous pouvez consulter les étapes de fonctionnement spécifiques détaillées ci-dessous. explication, les amis intéressés peuvent s'y référer.

Les fonctions en JS peuvent être soit des constructeurs, soit appelées comme fonctions ordinaires. Lorsque vous utilisez new pour créer un objet, la fonction correspondante est le constructeur, et lorsqu'elle est appelée via un objet, c'est une fonction ordinaire.

Il existe trois façons de créer des fonctions ordinaires : la déclaration explicite, la définition anonyme et la nouvelle fonction().

Lorsqu'un nouvel objet est créé via new, la couche inférieure de JS pointe la chaîne prototype du nouvel objet vers l'objet prototype du constructeur, ainsi une chaîne prototype est établie entre le nouvel objet et l'objet fonction . L'objet peut accéder aux méthodes et propriétés du prototype de l'objet fonction.

Comme d'autres langages de haut niveau, Javascript possède également des constructeurs et de nouveaux opérateurs. Nous savons que new est utilisé pour instancier une classe et allouer un objet instance en mémoire. Mais en Javascript, tout est objet. Pourquoi devons-nous utiliser new pour générer des objets ? Cet article vous amènera à explorer le mystère du nouveau en Javascript...

1 Apprenez à connaître le nouvel opérateur


function Animal(name){
this.name = name;
}
 Animal.color = "black";
 Animal.prototype.say = function(){
console.log("I'm " + this.name);
 };
 var cat = new Animal("cat");

 console.log(
 cat.name, //cat
 cat.color //undefined
 );
 cat.say(); //I'm cat

 console.log(
 Animal.name, //Animal
 Animal.color //back
 );
 Animal.say(); //Animal.say is not a function

2. Interprétation du code

Les lignes 1 à 3 créent une fonction Animal et définissent des attributs sur ce ceci : nom, nom. Les valeurs sont les paramètres formels de la fonction lors de son exécution.

La ligne 4 définit une propriété statique : la couleur sur l'objet Animal (l'Animal lui-même est un objet fonction), et attribue la valeur "noir"

Les lignes 5 à 7 définissent l'objet prototype du Fonction animale Une méthode say() est définie sur le prototype, et la méthode say génère la valeur de nom de celle-ci.

Ligne 8 crée un nouvel objet cat via le nouveau mot-clé

Lignes 10 à 14, l'objet cat essaie d'accéder aux attributs name et color et appelle la méthode say.

Lignes 16-20 L'objet Animal tente d'accéder aux propriétés name et color et appelle la méthode say.

3. Analyse clé

La 8ème ligne de code est la clé :

var cat = new Animal("cat");

Animal lui-même est une fonction ordinaire, mais lorsqu'un objet est créé via new, Animal est le constructeur.


Lorsque le moteur JS exécute ce code, il effectue beaucoup de travail en interne. Le pseudocode est utilisé pour simuler son workflow comme suit :


new Animal("cat") = {

var obj = {};

obj.__proto__ = Animal.prototype;

var result = Animal.call(obj,"cat");

return typeof result === 'object'? result : obj;
}
(1)

Créer un objet obj vide;

(2)

Pointez le proto de obj vers le prototype d'objet prototype du constructeur Animal, et puis créez obj La chaîne de prototypes de l'objet : obj->Animal.prototype->Object.prototype->null

(3)

Appelez la fonction Animal dans l'environnement d'exécution de l'objet obj et passez les paramètres" cat". Équivalent à var result = obj.Animal("cat").

(4)

Examinez la valeur de retour renvoyée à l'étape 3. S'il n'y a pas de valeur de retour ou si une valeur non-objet est renvoyée, obj sera renvoyé en tant que nouvel objet ; la valeur de retour sera utilisée comme nouvel objet. L'objet est renvoyé. Après avoir compris son mécanisme de fonctionnement, nous savons que cat est en fait la valeur de retour du processus (4), nous en savons donc plus sur l'objet cat :

La chaîne prototype de cat est:cat->Animal.prototype->Object.prototype->null

cat->Animal.prototype->Object.prototype->null<br>Un nouvel attribut est ajouté à cat : name


Après avoir analysé le processus de génération cat, regardons le résultat de sortie :

cat.name -> Dans le processus (3), l'objet obj génère l'attribut name. Par conséquent, cat.name est ici obj.name

cat.color -> cat recherchera d'abord sa propre couleur, et si elle n'est pas trouvée, elle recherchera le long de la chaîne de prototypes. nous utilisons uniquement la couleur de l'objet Animal qui est définie dessus, mais elle n'est pas définie sur sa chaîne de prototypes, elle est donc introuvable.

cat.say -> cat recherchera d'abord sa propre méthode say Si elle n'est pas trouvée, elle recherchera le long de la chaîne de prototypes. Dans l'exemple ci-dessus, nous avons défini say sur le prototype Animal. dans la chaîne de prototypes, j'ai trouvé la méthode say sur .

De plus, this.name est également accessible dans la méthode say. Ceci fait ici référence à son appelant obj, donc la valeur de obj.name est affichée.

Pour Animal, c'est aussi un objet lui-même, il obéit donc également aux règles de recherche ci-dessus lors de l'accès aux propriétés et aux méthodes, donc :

Animal.color -> "black"

Animal.name -> "Animal", Animal recherche d'abord son propre nom et trouve le nom, mais ce nom n'est pas le nom que nous avons défini, mais une propriété intégrée de l'objet fonction.

Généralement, lorsqu'un objet fonction est généré, il aura un attribut de nom intégré et utilisera le nom de la fonction comme valeur d'affectation (uniquement les objets fonction).

Animal.say -> Animal ne trouve pas la méthode say en lui-même, et recherchera également le long de sa chaîne de prototypes. Qu'est-ce que la chaîne de prototypes d'Animal ?

D'après les résultats du test : La chaîne de prototypes d'Animal ressemble à ceci :


Animal->Function.prototype->Object.prototype->null


Il n'y a donc pas de méthode say définie sur la chaîne de prototypes d'Animal !

4. Le sens de l'existence du nouveau

认识了new运算符之后,我们再回到开篇提到的问题:JS中万物皆对象,为什么还要通过new来产生对象?

要弄明白这个问题,我们首先要搞清楚cat和Animal的关系:

通过上面的分析,我们发现cat继承了Animal中的部分属性,因此我们可以简单的理解:Animal和cat是继承关系。

另一方面,cat是通过new产生的对象,那么cat到底是不是Animal的实例对象? 我们先来了解一下JS是如何来定义“实例对象”的?

A instanceof B
如果上述表达式为true,JS认为A是B的实例对象,我们用这个方法来判断一下cat和Animal

cat instanceof Animal; //true
从执行结果看:cat确实是Animal实例,要想证实这个结果,我们再来了解一下JS中instanceof的判断规则:


var L = A.__proto__;
var R = B.prototype;
if(L === R)
return true;

如果A的proto 等价于 B的prototype,就返回true

在new的执行过程(2)中,cat的proto指向了Animal的prototype,所以cat和Animal符合instanceof的判断结果。

因此,我们认为:cat 是Animal的实例对象。

5、总结

在Javascript中, 通过new可以产生原对象的一个实例对象,而这个实例对象继承了原对象的属性和方法。因此,new存在的意义在于它实现了Javascript中的继承,而不仅仅是实例化了一个对象!

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn