Maison  >  Article  >  interface Web  >  Qu'est-ce qu'un constructeur ? Explication détaillée des constructeurs en JavaScript

Qu'est-ce qu'un constructeur ? Explication détaillée des constructeurs en JavaScript

青灯夜游
青灯夜游avant
2022-08-04 15:22:392846parcourir

En tant que base des prototypes et des chaînes de prototypes, comprendre d'abord le constructeur et son processus d'exécution peut mieux nous aider à acquérir la connaissance des prototypes et des chaînes de prototypes. Cet article vous amènera à en apprendre davantage sur le constructeur en JavaScript et à vous présenter comment utiliser le constructeur pour créer un objet js. J'espère qu'il vous sera utile !

Qu'est-ce qu'un constructeur ? Explication détaillée des constructeurs en JavaScript

1. Qu'est-ce qu'un constructeur ?

Lorsqu'une fonction commune est utilisée pour créer un objet de classe, elle est appelée constructeur, ou constructeur. (Pour faciliter la compréhension, vous pouvez comprendre la création de constructeurs en JavaScript comme la création de classes dans d'autres langages. Le but est de l'utiliser pour instancier un objet via new)

function Person(){
//...
}
//当做普通函数调用
var obj=Person();

//构造函数调用
	 var obj=new Person();

Caractéristiques du constructeur :

  • Dans les conventions d'écriture, nous avons l'habitude de mettre en majuscule la première lettre des noms de constructeurs.

  • Créez un objet grâce au nouveau.

  • Il y a une valeur de retour sans écrire return à l'intérieur, et ce qui est renvoyé est un objet.

Utiliser le constructeur pour créer un objet js

  • Le constructeur crée l'objet (la méthode est écrite dans le constructeur, inconvénient : à chaque fois que le constructeur est exécuté, une méthode sera créée.)

	  function Person(name,age,gender){
            this.name=name;
            this.age=age;
            this.gender=gender;
            // 方法写在里面
            this.sayName=function(){
                 console.log(this.name);
             }      
          }
    
          function Dog(name,age){
              this.name=name;
              this.age=age;
          }
         
          var obj=new Person("张三",18,"男");
          var obj1=new Person("李四",16,"男");
          
          var dog=new Dog("乐乐",2);
          obj.sayName();
          obj1.sayName();
          
          console.log(obj);
          console.log(obj1);
          console.log(dog);
  • Le constructeur crée l'objet (la méthode est écrite en dehors du constructeur, inconvénient : la méthode est une méthode globale, polluant le monde entier.)

	   function Person(name,age,gender){
            this.name=name;
            this.age=age;
            this.gender=gender;
            this.sayName=fun;   //方法写在外面
          }
    	 function fun(){
            console.log(this.name);
        }
          function Dog(name,age){
              this.name=name;
              this.age=age;
          }
          
          var obj=new Person("张三",18,"男");
          var obj1=new Person("李四",16,"男");
          
          var dog=new Dog("乐乐",2);
          obj.sayName();
          obj1.sayName();
          
          console.log(obj);
          console.log(obj1);
          console.log(dog);
  • Le constructeur crée l'objet et transforme (le La méthode est créée via l'objet prototype)

Objet prototype :prototype

Chaque fonction que nous créons, l'analyseur ajoutera un attribut prototype à la fonction.

Pointe vers l'objet prototype du constructeur, nous pouvons accéder à cette propriété via __proto__.

Constructor.prototype.xxx, xxx peut être une variable ou une méthode. Pendant le processus d'exécution, il recherchera d'abord des méthodes ou des variables dans l'objet. S'il ne peut pas les trouver, il les recherchera dans le prototype.

	  function Person(name,age,gender){
            this.name=name;
            this.age=age;
            this.gender=gender;
          }
          function Dog(name,age){
              this.name=name;
              this.age=age;
          }
          
        /*为person添加统一的方法, 到原型对象中*/
        Person.prototype.sayName=function(){
            console.log(this.name);
        }
          var obj=new Person("张三",18,"男");
          var obj1=new Person("李四",16,"男");
          
          var dog=new Dog("乐乐",2);
          obj.sayName();
          obj1.sayName();
          
          console.log(obj);
          console.log(obj1);
          console.log(dog);

Résultats de l'opération :

Quest-ce quun constructeur ? Explication détaillée des constructeurs en JavaScript

2. Pourquoi utiliser le constructeur ?

Apprenez chaque concept non seulement en sachant de quoi il s'agit, mais aussi pourquoi et quel type de problème il résout.

Par exemple, nous voulons saisir les informations personnelles de chaque élève de la classe de première année, puis nous pouvons créer des objets, tels que :

var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
var p3 = { name: 'ww', age: 6, gender: '女', hobby: 'singing' };
var p4 = { name: 'zl', age: 6, gender: '男', hobby: 'football' };
// ...

Comme ci-dessus, nous pouvons traiter les informations de chaque élève comme des objets à traiter . Cependant, nous constaterons que nous écrivons à plusieurs reprises beaucoup de code dénué de sens. Tels que le nom, l’âge, le sexe, le passe-temps. S'il y a 60 élèves dans cette classe, nous devons l'écrire 60 fois.

A cette époque, les avantages du constructeur se reflètent. Nous avons constaté que même si chaque élève possède des attributs tels que le nom, le sexe et le passe-temps, ils sont tous différents. Nous transmettons donc ces attributs en tant que paramètres du constructeur. Et comme ce sont tous des étudiants de première année, leur âge est essentiellement de 6 ans, nous pouvons donc les écrire et les traiter individuellement lorsque nous sommes confrontés à des situations particulières. À ce stade, nous pouvons créer la fonction suivante :

function Person(name, gender, hobby) {
    this.name = name;
    this.gender = gender;
    this.hobby = hobby;
    this.age = 6;
}

Après avoir créé la fonction ci-dessus, nous pouvons l'appeler via le nouveau mot-clé, c'est-à-dire créer l'objet via le constructeur.

var p1 = new Person('zs', '男', 'basketball');
var p2 = new Person('ls', '女', 'dancing');
var p3 = new Person('ww', '女', 'singing');
var p4 = new Person('zl', '男', 'football');
// ...

À ce stade, vous constaterez que créer des objets deviendra très pratique. Par conséquent, même si le processus d'encapsulation du constructeur sera plus fastidieux, une fois l'encapsulation réussie, il nous sera très facile de créer des objets, c'est pourquoi nous utilisons des constructeurs.

Lors de l'utilisation de littéraux d'objet pour créer une série d'objets du même type, ces objets peuvent avoir des caractéristiques (propriétés) et des comportements (méthodes) similaires. À ce stade, de nombreux codes répétés seront générés, ce qui peut être réalisé. en utilisant des constructeurs代码复用 .

3. Le processus d'exécution du constructeur

Parlons d'abord de quelques concepts de base.

function Animal(color) {
 this.color = color;
}

Lorsqu'une fonction est créée, on ne sait pas si c'est un constructeur Même si le nom de la fonction est en majuscules comme dans l'exemple ci-dessus, on ne peut pas en être sûr. Ce n'est que lorsqu'une fonction est appelée avec le mot-clé new que l'on peut dire qu'il s'agit d'un constructeur. Tout comme ce qui suit :

var dog = new Animal("black");

Ci-dessous, nous discutons uniquement du processus d'exécution du constructeur, c'est-à-dire lorsqu'il est appelé avec le nouveau mot-clé.

Prenons la personne ci-dessus comme exemple.

function Person(name, gender, hobby) {
 this.name = name;
 this.gender = gender;
 this.hobby = hobby;
 this.age = 6;
}

var p1 = new Person('zs', '男', 'basketball');

À ce stade, le constructeur aura les processus d'exécution suivants :

1) Lorsqu'il est appelé avec le nouveau mot-clé, un nouvel espace mémoire sera créé, étiqueté comme une instance d'Animal.

2) Cet intérieur du corps de fonction pointe vers la mémoire

Grâce aux deux étapes ci-dessus, nous pouvons tirer cette conclusion.

var p2 = new Person('ls', '女', 'dancing');  // 创建一个新的内存 #f2
var p3 = new Person('ww', '女', 'singing');  // 创建一个新的内存 #f3

Chaque fois qu'une instance est créée, un nouvel espace mémoire (#f2, #f3) sera créé. Lorsque #f2 est créé, celui-ci à l'intérieur du corps de la fonction pointe vers #f2. Lorsque #f3 est créé, le corps de la fonction interne. cela pointe vers #f3.

3) 执行函数体内的代码
通过上面的讲解,你就可以知道,给 this 添加属性,就相当于给实例添加属性。

4)默认返回 this

由于函数体内部的this指向新创建的内存空间,默认返回 this ,就相当于默认返回了该内存空间,也就是上图中的 #f1。此时,#f1的内存空间被变量p1所接受。也就是说 p1 这个变量,保存的内存地址就是 #f1,同时被标记为 Person 的实例。

以上就是构造函数的整个执行过程。

4、构造函数的返回值

构造函数执行过程的最后一步是默认返回 this 。言外之意,构造函数的返回值还有其它情况。下面我们就来聊聊关于构造函数返回值的问题。

1)没有手动添加返回值,默认返回 this

function Person1() {
 this.name = 'zhangsan';
}

var p1 = new Person1();

按照上面讲的,我们复习一遍。首先,当用 new 关键字调用时,产生一个新的内存空间 #f11,并标记为 Person1 的实例;接着,函数体内部的 this 指向该内存空间 #f11;执行函数体内部的代码;由于函数体内部的this 指向该内存空间,而该内存空间又被变量 p1 所接收,所以 p1 中就会有一个 name 属性,属性值为 ‘zhangsan’。

p1: {
 name: 'zhangsan'
}

2)手动添加一个基本数据类型的返回值,最终还是返回 this

function Person2() {
 this.age = 28;
 return 50;
}

var p2 = new Person2();
console.log(p2.age);   // 28
p2: {
 age: 28
}

如果上面是一个普通函数的调用,那么返回值就是 50。

3)手动添加一个复杂数据类型(对象)的返回值,最终返回该对象

直接上例子

function Person3() {
 this.height = '180';
 return ['a', 'b', 'c'];
}

var p3 = new Person3();
console.log(p3.height);  // undefined
console.log(p3.length);  // 3
console.log(p3[0]);      // 'a'

再来一个例子

function Person4() {
  this.gender = '男';
  return { gender: '中性' };
}

var p4 = new Person4();
console.log(p4.gender);  // '中性'

5、构造函数首字母必须大写吗?

大小写都可以

6、不用new关键字,直接运行构造函数,是否会出错?

如果不会出错,那么,用new和不用new调用构造函数,有什么区别?

1)使用new操作符调用函数

例子:

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = new Person('nicole');
person1.say(); // "I am nicole"

用new调用构造函数,函数内部会发生如下变化:

创建一个this变量,该变量指向一个空对象。并且该对象继承函数的原型;
属性和方法被加入到this引用的对象中;
隐式返回this对象(如果没有显性返回其他对象)
用伪程序来展示上述变化:

function Person(name){
  // 创建this变量,指向空对象
  var this = {}; 
  // 属性和方法被加入到this引用的对象中
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  // 返回this对象
  return this;
}

可以看出,用new调用构造函数,最大特点为,this对象指向构造函数生成的对象,所以,person1.say()会返回字符串: “I am nicole”。

小贴士:如果指定了返回对象,那么,this对象可能被丢失。

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  var that = {};
  that.name = "It is that!";
  return that;
}

var person1 = new Person('nicole');
person1.name; // "It is that!"

2)直接调用函数

如果直接调用函数,那么,this对象指向window,并且,不会默认返回任何对象(除非显性声明返回值)。

还是拿Person函数为例,直接调用Person函数:

var person1 = Person('nicole');
person1; // undefined
window.name; // nicole

可见,直接调用构造函数的结果,并不是我们想要的。

3)小结

为了防止因为忘记使用new关键字而调用构造函数,可以加一些判断条件强行调用new关键字,代码如下:

function Person(name){
  if (!(this instanceof Person)) {
    return new Person(name);
  }
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = Person('nicole');
console.log(person1.say()); // I am nicole
var person2 = new Person('lisa');
console.log(person2.say()); // I am lisa

【相关推荐: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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer