J'ai beaucoup appris récemment en apprenant JavaScript et le prototype en js orienté objet. S'il y a quelque chose qui ne va pas, j'espère que vous pourrez me corriger.
En tant que langage orienté objet, js a naturellement le concept d'héritage, mais il n'y a pas de concept de classes en js, et il n'y a pas d'extension similaire à java. Par conséquent, je pense que l'héritage en js repose principalement sur le prototype (chaîne. ) en js.
Alors, qu’est-ce qu’un prototype ? Nous savons qu'une fonction en js est aussi un objet. Lorsque nous créons une fonction, la fonction a en fait un attribut appelé prototype par défaut. Ce type d'attribut est appelé attribut prototype. C'est un pointeur qui pointe vers le prototype de la fonction. . Objet, cet objet prototype a un attribut par défaut appelé constructeur, qui pointe vers la fonction avec l'attribut protptype.
function Person(){} Person.prototype={ // constructor:Person; first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} };
Prenons ceci comme exemple. Nous créons d'abord une fonction Person. Cette fonction a un prototype d'attribut par défaut, pointant vers l'objet Person.propttype. Cet objet a un constructeur d'attribut par défaut (), Person.prototype.constructor-- - >Personne. (En fait, la valeur par défaut ici est de pointer vers Objet, je le corrigerai plus tard)
Que se passe-t-il lorsque nous créons une instance via le constructeur ?
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} }; var boy=new Person(); var girl=new Person();
À ce stade, nous devons savoir que la différence entre les constructeurs et les fonctions en js est le nouveau mot-clé, et qu'une fonction utilisant l'opérateur new est un constructeur. Lorsque nous créons un objet instance de Person et que nous l'enregistrons dans boy et girl, ces deux objets instances génèrent un attribut par défaut appelé _proto_ (qui peut être représenté par [[prototype]] dans ECMAScript5. Cet attribut pointe vers le constructeur Le prototype). objet de la fonction, qui est boy._proto_--->Person.prototype (n'a rien à voir avec le constructeur). À ce stade, un garçon ou une fille peut appeler les attributs de l'objet prototype par des points. À ce stade, vous devez savoir que le garçon et la fille partagent les attributs de l'objet prototype. Nous pouvons vérifier la conclusion ci-dessus via isProtptypeOf() ou object.getPrototypeOf() (la valeur de retour de cette fonction est l'objet prototype, qui est la valeur de _proto_).
alert(Person.prototype.isPrototypeOf(boy)); //true alert(Object.getPrototypeOf(boy).first_name); //"guo"
À ce stade, nous pouvons effectuer une vérification plus approfondie. Que se passera-t-il si une propriété portant le même nom que la propriété de l'objet prototype est créée dans l'instance ?
var boy=new Person(); var girl=new Person(); boy.hair_color="red"; alert(boy.hair_color); //red alert(girl.hair_color); //black alert(Object.getPrototypeOf(boy).hair_color); //black
On peut voir que l'attribut du même nom déclaré dans l'instance bloquera l'attribut dans l'objet prototype, mais il ne l'écrasera que temporairement et n'affectera pas le type d'attribut de l'objet prototype (Object.getPrototypeOf( boy).hair_color== black), cela n'affectera pas les autres objets d'instance qui partagent le type de propriété d'objet prototype (girl.hair_color==black). Dans le même temps, vous pouvez utiliser l'opérateur delete pour supprimer les attributs déclarés par l'objet instance afin d'annuler l'effet de blocage. Nous pouvons utiliser hasOwnProperty() pour vérifier si une propriété existe dans l'instance (true) ou dans l'objet prototype (false).
alert(boy.hasOwnProperty("hair_color")); //true
Les propriétés peuvent être énumérées à l'aide de Object.keys().
var key=Object.keys(Person.prototype); alert(key);
Après avoir appris cela, nous constaterons que l'utilisation de la méthode d'écriture ci-dessus pour déclarer un objet prototype posera un problème. Le constructeur ne pointe plus vers Person. C'est contraire à ce que nous avons dit selon lequel l'attribut constructeur de l'objet prototype pointe. à la fonction contenant l'attribut prototype par défaut. En effet : chaque fois qu'une fonction est créée, un objet prototype est automatiquement créé, et cet objet crée un constructeur par défaut. Par conséquent, notre essence ici est de réécrire le prototype par défaut, de sorte que le nouveau constructeur pointe également vers la fonction Objet et ne pointe plus vers la fonction Personne. Si le constructeur est vraiment important, alors vous devez écrire constructor:Person.
Après cela, nous devons connaître la dynamique du prototype. La modification des propriétés de l'objet prototype sera reflétée dans l'instance, que l'instance soit créée avant ou après la modification du type de propriété de l'objet prototype. 🎜>
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} }; var boy=new Person(); Person.prototype.hobby="basketball"; var girl=new Person(); alert(boy.hobby); //basketball
Cependant, cette situation ne se produit que lorsque les propriétés de l'objet prototype sont modifiées. Lorsque les propriétés de l'objet prototype sont complètement réécrites, la création de l'instance doit être placée après la réécriture des propriétés de l'objet prototype, sinon une erreur se produira.
function Person(){} var girl=new Person(); Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} }; var boy=new Person(); Person.prototype.hobby="basketball"; alert(boy.hobby); //basketball alert(girl.first_name); //undefined
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", friends:["Nick","John"], city:"zhengzhou", act:function(){alert("eatting");} }; var boy=new Person(); boy.friends.push("Mike"); var girl=new Person(); alert(boy.friends); //Nick,John,Mike alert(girl.friends); //Nick,John,MIke
function Person(hair_color,city){ this.hair_color=hair_color; this.city=city; this.friends=["John","Nick"]; } Person.prototype={ constructor:Person, first_name:"guo", act:function() { alert("eatting"); } }; var boy=new Person("black","zhengzhou"); var girl=new Person("red","shenyang"); boy.friends.push("Nick"); alert(girl.friends); alert(boy.friends);
Ce mode est actuellement la méthode la plus utilisée et la plus reconnue pour créer des types personnalisés dans ECMAScript, et peut même être utilisé comme mode par défaut.
Mais pour les programmeurs travaillant dans d'autres langages orientés objet, ce modèle semble étrange. Afin d'encapsuler toutes les informations dans le constructeur, le modèle de prototype dynamique est apparu. Le mode dynamique utilise principalement une instruction if pour déterminer si l'objet prototype doit être initialisé pour économiser des ressources.
De plus, il existe un mode de construction sécurisé pour s'adapter aux situations où il n'y a pas d'attributs partagés et celui-ci n'est pas utilisé.
L'analyse du prototype ci-dessus en javaScript [recommandé] correspond à tout le contenu partagé par l'éditeur. J'espère qu'elle pourra vous donner une référence et j'espère que vous soutiendrez Script Home.