javascript - Comment combiner un modèle de constructeur et un modèle de prototype en JS
曾经蜡笔没有小新
曾经蜡笔没有小新 2017-05-19 10:33:10
0
5
653

La méthode d'écriture en programmation avancée est la suivante

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
}
Person.prototype = {
    constructor: Person,
    getName: function(){
        return this.name;
    }
}

Donc si je l'écris comme ça, est-ce pareil ? La seule différence est que leurs constructeurs sont différents ?

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
    Person.prototype.getName = function(){
        return this.name;
    }
}
曾经蜡笔没有小新
曾经蜡笔没有小新

répondre à tous(5)
洪涛

Quelle est la différence entre écrire la définition (emplacement) du prototype à l'intérieur ou à l'extérieur du constructeur ?

La deuxième façon d'écrire effectuera l'opération sur le prototype à chaque fois qu'une instance est créée ! Le fait est que cette opération n’a aucun sens et que cette méthode est la même pour chaque instance.
Dans la première méthode, lorsque le prototype est écrit en dehors du constructeur, le problème de définition répétée ou d'allocation de mémoire peut être résolu à la fois formellement et via l'allocation de mémoire.
Correspond à la première façon d'écrire en mémoire. Peu importe le nombre d'instances que vous créez, chaque instance n'occupe que le nom, l'âge, le métier et les leçons. Il n'y a qu'une seule copie de getName en mémoire, partagée par toutes les instances ; la deuxième façon d'écrire, Chaque instance nouvellement créée allouera un espace supplémentaire (pile) pour exécuter la définition du prototype.

Quelle est la différence entre la façon dont les valeurs sont attribuées au prototype dans la première méthode et dans la deuxième méthode ?

La différence est très grande. Une fois qu'une classe de fonction est définie, sa propriété constructeur par défaut est elle-même, et son instance renverra cette valeur lors de l'accès à la propriété constructeur.

function Person() {};
console.log(Person.prototype.constructor);  // Person

var p = new Person();
console.log(p.constructor);   // Person    表示p的构造函数是Person类

Pourquoi devez-vous définir le constructeur dans la méthode 1 ? Parce qu'il réaffecte le prototype si vous ne définissez pas le constructeur (Person.prototype = {getName: function() {}}) , alors ce qui précède Dans l'exemple, la valeur de retour de p.constructor sera Object, c'est-à-dire que le constructeur de p est Object, ce qui est évidemment incompatible avec les faits . Person.prototype = {getName: function() {}}),那么上例中p.constructor返回值将是 Object, 即p的构造函数是Object,显然与事实不符。

方法1更明智的做法是不要重新给prototype赋值,只为prototype添加我们需要的属性getName, 改为 Person.prototype.getName = function() {return this.name;}

L'approche la plus judicieuse de la méthode 1 n'est pas de réaffecter le prototype, mais simplement d'ajouter l'attribut getName dont nous avons besoin au prototype et de le remplacer par Person.prototype.getName = function() {renvoyez ceci. name;} code>, qui est la méthode de définition dans la deuxième méthode, est écrite de cette manière afin qu'elle ne remplace pas les propriétés par défaut du prototype. #🎜🎜#
習慣沉默
首先,你应该搞清楚js中的原型,在js中,原型指的是构造函数的prototype属性的值,由构造函数创建出来的实例会自动链接到原型对象也就是其构造函数的prototype属性上。
    function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
}
Person.prototype = {
    constructor: Person,
    getName: function(){
        return this.name;
    }
}
这个写法中,Person为构造函数,可以创建出一个实例对象,
var p=new Person();
然后p可以继承原型中的属性,在原型中constructor指向的是当前的构造函数
你的写法可以理解为在构造函数中给原型的getname属性赋值了一个函数
PHPzhong

L'ancienne façon d'écrire réécrit le prototype, et votre façon d'écrire ajoute simplement une méthode au prototype. Les deux sont des manières différentes

.
世界只因有你

Selon la façon dont vous l'écrivez, l'espace de stockage sera réaffecté à l'instance lors de chaque processus d'instanciation. L'une des significations du modèle de prototype est que toutes les instances peuvent partager les attributs et les méthodes du prototype, même si cela seul présente des défauts. . Le deuxième point est que je préfère toujours écrire le prototype objet objet littéral. Je pense personnellement que l'un est plus intuitif, et le second est propice à la maintenance. Comme suit :

    Person.prototype = {
        constructor: Person,
        getName: function(){
            return this.name;
        }
    }

Assurez-vous d'écrire l'attribut constructeur, sinon une erreur de pointage se produira. A ce moment, l'objet prototype est réécrit si cet attribut n'est pas spécifié, la chaîne prototype ne pourra pas jouer son rôle.

为情所困

Il existe de nombreuses différences entre l'héritage prototypique et les constructeurs. L'héritage prototypique est un héritage de chaîne de prototypes.

La chaîne prototype n'est pas parfaite, elle contient les deux problèmes suivants.

Question 1 : Lorsque la chaîne de prototypes contient un prototype d'une valeur de type référence, la valeur de type référence sera partagée par toutes les instances ;

Problème 2 : lors de la création d'un sous-type (comme la création d'une instance de Son), les paramètres ne peuvent pas être transmis au constructeur du supertype (comme Father).

Compte tenu de cela, en pratique la chaîne prototype est rarement utilisée seule.

À cette fin, quelques tentatives seront présentées ci-dessous pour combler les lacunes de la chaîne de prototypes.

Emprunteur constructeur

Afin de résoudre les deux problèmes ci-dessus dans la chaîne de prototypes, nous avons commencé à utiliser une technologie appelée emprunt de constructeur (vol de constructeur) (également appelé héritage classique).

Idée de base : appeler le constructeur de supertype à l'intérieur du constructeur de sous-type.

function Father(){
    this.colors = ["red","blue","green"];
}
function Son(){
    Father.call(this);//继承了Father,且向父类型传递参数
}
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"

var instance2 = new Son();
console.log(instance2.colors);//"red,blue,green" 可见引用类型值是独立的

Evidemment, emprunter aux constructeurs résout d'un seul coup les deux problèmes majeurs de la chaîne de prototypes :

Premièrement, il assure l'indépendance des valeurs de type référence dans la chaîne de prototypes et n'est plus partagé par toutes les instances ;

Deuxièmement, lors de la création d'un sous-type, vous pouvez également transmettre des paramètres au type parent.

Suite à cela, si vous empruntez uniquement le constructeur, vous ne pourrez pas éviter les problèmes du modèle de constructeur - les méthodes sont toutes définies dans le constructeur, donc la réutilisation des fonctions n'est pas disponible et le super type Méthodes est défini. in (comme Father) sont également invisibles pour les sous-types. Compte tenu de cela, la technique d'emprunt de constructeurs est rarement utilisée seule.
Pour plus d'informations, veuillez vous référer à la chaîne de prototypes JS et à l'héritage. vous l'aimez, n'hésitez pas à mettre un pouce bleu et à le soutenir, merci !

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal