En Javascript, tout est un objet, mais les objets sont également différents et peuvent être grossièrement divisés en deux catégories, à savoir : les objets ordinaires (Object) et les objets fonctionnels (Function).
De manière générale, les objets générés via new Function sont des objets de fonction et les autres objets sont des objets ordinaires.
Exemple :
function f1(){ //todo } var f2 = function(){ //todo }; var f3 = new Function('x','console.log(x)'); var o1 = {}; var o2 = new Object(); var o3 = new f1(); console.log( typeof f1,//function typeof f2,//function typeof f3,//function typeof o1,//object typeof o2,//object typeof o3 //object ); >> function function function object object object
f1 appartient à la déclaration d'une fonction. La façon la plus courante de définir une fonction est que f2 est en fait une fonction anonyme. , qui appartient à la fonction Expression, f3 n'est pas courant, mais c'est aussi un objet fonction.
Function est un objet fourni avec JS. Lorsque f1 et f2 sont créés, JS construira automatiquement ces objets via new Function(). Par conséquent, ces trois objets sont tous créés via new Function().
Il existe deux manières de créer des objets en Javascript : les littéraux d'objet et l'utilisation de nouvelles expressions. La création de o1 et o2 correspond à ces deux méthodes. Concentrons-nous sur o3. Si vous utilisez les idées Java et C# pour comprendre, o3 est un objet instance de f1, et o3 et f1 sont du même type, du moins je le pensais, mais ce n'est pas le cas...
Alors, comment le comprenez-vous ? , voyez si o3 passe une nouvelle fonction. Ce qui est généré ne l'est évidemment pas, puisque ce n'est pas un objet fonction, c'est un objet ordinaire.
Après une simple compréhension des objets fonction et des objets ordinaires, jetons un coup d'œil au prototype et à la chaîne de prototypes en Javascript :
En JS, chaque fois qu'un objet fonction f1 est créé, il y a certains attributs intégrés à l'objet, notamment prototype et __proto__ prototype est l'objet prototype, qui enregistre certains attributs et méthodes de f1.
Il est à noter que prototype est invisible pour f1, c'est-à-dire que f1 ne cherchera pas les propriétés et méthodes dans prototype.
function f(){} f.prototype.foo = "abc"; console.log(f.foo); //undefined
Alors, à quoi sert un prototype ? En fait, la fonction principale du prototype est l’héritage. En termes simples, les propriétés et méthodes définies dans le prototype sont réservées à ses propres « descendants ». Par conséquent, les sous-classes peuvent accéder pleinement aux propriétés et méthodes du prototype.
Pour savoir comment la f1 laisse le prototype aux "descendants", nous devons comprendre la chaîne de prototypes dans JS. À ce moment-là, __proto__ dans JS entre en scène. profond, donc vous ne le voyez souvent pas, mais il existe à la fois dans les objets ordinaires et dans les objets fonction. Sa fonction est de sauvegarder l'objet prototype de la classe parent. Lorsque JS crée un objet via la nouvelle expression, il s'agit généralement du prototype de. la classe parent sera affectée à l'attribut __proto__ du nouvel objet, formant ainsi un héritage générationnel...
function f(){} f.prototype.foo = "abc";var obj = new f(); console.log(obj.foo); //abc
Maintenant nous savons que __proto_ dans obj _Le prototype de f est enregistré, alors qu'est-ce qui est enregistré dans __proto__ dans le prototype de f ? Regardez l'image ci-dessous :
Comme le montre l'image, le __proto__ du prototype stocke l'objet. prototype, et l'objet Object.prototype a également __proto__. D'après les résultats de sortie, Object.prototype.__proto__ est nul, indiquant la fin de la chaîne de prototype d'objet obj. Comme le montre la figure ci-dessous :
Une fois que l'objet obj a une telle chaîne de prototypes, lorsque obj.foo est exécuté, obj recherchera d'abord s'il a cet attribut, mais ne recherchera pas. propre prototype, lorsque foo ne peut pas être trouvé, obj recherchera le long de la chaîne de prototypes...
Dans l'exemple ci-dessus, nous avons défini l'attribut foo sur le prototype de f, puis obj recherchera cette propriété. être retrouvé sur la chaîne prototype et exécuté.
Enfin, résumez les points clés impliqués dans cet article en quelques phrases :
La formation de la chaîne de prototypes dépend vraiment on_ _proto__ au lieu de prototype. Lorsque le moteur JS exécute la méthode d'un objet, il vérifie d'abord si la méthode existe dans l'objet lui-même. Si elle n'existe pas, il recherchera sur la chaîne de prototypes, mais pas sur son propre prototype.
Le __proto__ d'un objet enregistre sa propre chaîne de prototypes et détermine son propre type de données. Changer __proto__ équivaut à changer le type de données de l'objet.
Le prototype d'une fonction n'appartient pas à sa propre chaîne de prototypes. Il est le cœur de la création de sous-classe, détermine le type de données de la sous-classe et constitue le pont reliant la chaîne de prototypes. de la sous-classe.
Le but de la définition de méthodes et de propriétés sur l'objet prototype doit être hérité et utilisé par les sous-classes.