Maison  >  Article  >  interface Web  >  L'explication la plus détaillée du prototype JS et de la chaîne de prototypes

L'explication la plus détaillée du prototype JS et de la chaîne de prototypes

hzc
hzcavant
2020-06-24 09:50:121772parcourir

1. Objets ordinaires et objets fonctionnels

En JavaScript, tout est un objet ! Mais les objets sont aussi différents. Divisés en objets ordinaires et objets fonction, Object et Function sont des objets fonction fournis avec JS. L'exemple suivant illustre

 var o1 = {}; 
 var o2 =new Object(); var o3 = new f1(); 
 function f1(){}; 
 var f2 = function(){}; var f3 = new Function('str','console.log(str)');
 
 console.log(typeof Object); //function 
 console.log(typeof Function); //function   
 console.log(typeof f1); //function 
 console.log(typeof f2); //function 
 console.log(typeof f3); //function    
 console.log(typeof o1); //object 
 console.log(typeof o2); //object 
 console.log(typeof o3); //object

Dans l'exemple ci-dessus, o1 o2 o3 est un objet ordinaire et f1 f2 f3 est un objet fonction. Comment distinguer est en fait très simple. Tous les objets créés via new Function() sont des objets fonction, et les autres sont des objets ordinaires. f1, f2, sont tous créés via new Function() en dernière analyse. Les objets de fonction sont également créés via New Function().

Assurez-vous de faire la distinction entre les objets ordinaires et les objets fonctionnels. Nous l'utiliserons fréquemment ci-dessous.

2. Constructeur

Passons d'abord en revue les connaissances du constructeur :

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function() { alert(this.name) } 
 }
 var person1 = new Person('Zaxlct', 28, 'Software Engineer');
 var person2 = new Person('Mick', 23, 'Doctor');

L'exemple ci-dessus Person1 et person2 sont tous deux des instances de Person. Les deux instances ont une propriété constructor (constructeur) qui pointe vers Person. C'est-à-dire :

   console.log(person1.constructor == Person); //true
   console.log(person2.constructor == Person); //true

Nous devons nous rappeler deux concepts (constructeur, instance) : personne1 et personne2 sont toutes deux des instances du constructeur Personne Une formule : L'attribut constructeur de l'instance pointe vers le constructeur.

3. Objet prototype

En JavaScript, chaque fois qu'un objet (une fonction est aussi un objet) est défini, l'objet Contient certaines propriétés prédéfinies. Chaque objet fonction possède un attribut prototype, qui pointe vers l'objet prototype de la fonction. (Utilisez ce qui est __proto__ en premier et nous l'analyserons en détail dans la deuxième leçon)

 function Person() {}
 Person.prototype.name = 'Zaxlct';
 Person.prototype.age  = 28;
 Person.prototype.job  = 'Software Engineer';
 Person.prototype.sayName = function() {
   alert(this.name);
 }   
 var person1 = new Person();
 person1.sayName(); // 'Zaxlct' 
 var person2 = new Person();
 person2.sayName(); // 'Zaxlct' 
 console.log(person1.sayName == person2.sayName); //true

Nous avons obtenu la première "Loi" de cet article :

 每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性

Alors, qu'est-ce qu'un objet prototype ? Si on change l'exemple ci-dessus, vous comprendrez :

Person.prototype = {
    name:  'Zaxlct',
    age: 28,
    job: 'Software Engineer',
    sayName: function() {
      alert(this.name);
    }
 }

Objet prototype, comme son nom l'indique, c'est un objet ordinaire (non-sens = =!). A partir de maintenant, vous devez vous rappeler que l'objet prototype est Person.prototype. Si vous en avez toujours peur, pensez-y comme à la lettre A : var A = Person.prototype


. Ci-dessus, nous avons ajouté quatre attributs à A : nom, âge, emploi, sayName. En fait, il a également un attribut par défaut : constructor

Par défaut, tous les objets prototypes seront automatiquement Obtenez un attribut (constructeur) de constructor, qui (est un pointeur) pointe vers la fonction (Personne) où se trouve l'attribut prototype

La phrase ci-dessus est un peu difficile à prononcer. Traduisons-la : A a un attribut constructor par défaut, qui est un pointeur pointant. à la Personne. C'est-à-dire : Person.prototype.constructor == Person


Dans la deuxième section "Constructeur" ci-dessus, nous savons que l'attribut constructeur (constructeur) de l'instance pointe vers le constructeur  : person1.constructor == Person

Ces deux "formules" semblent quelque peu liées :

 person1.constructor == Person
 Person.prototype.constructor == Person

Pourquoi person1 a-t-il l'attribut constructeur ? C'est parce que person1 est une instance de Person. Alors pourquoi Person.prototype a-t-il un attribut constructeur ? ? De même, Person.prototype (considérez-le comme A) est également une instance de Person. Autrement dit, lorsque Person est créé, un objet instance de celui-ci est créé et attribué à son prototype. Le processus de base est le suivant : <.>

var A = new Person();
Person.prototype = A; // 注:上面两行代码只是帮助理解,并不能正常运行

结论:原型对象(Person.prototype)是 构造函数(Person)的一个实例。


原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:

  function Person(){};
  console.log(Person.prototype) //Person{}
  console.log(typeof Person.prototype) //Object
  console.log(typeof Function.prototype) // Function,这个特殊
  console.log(typeof Object.prototype) // Object
  console.log(typeof Function.prototype.prototype) //undefined

Function.prototype 为什么是函数对象呢?

  var A = new Function ();
  Function.prototype = A;

上文提到凡是通过 new Function( ) 产生的对象都是函数对象。因为 A 是函数对象,所以Function.prototype 是函数对象。

那原型对象是用来做什么的呢?主要作用是用于继承。举个例子:

var Person = function(name){
     this.name = name; // tip: 当函数执行时这个 this 指的是谁?
   };
   Person.prototype.getName = function(){
     return this.name;  // tip: 当函数执行时这个 this 指的是谁?
   }
   var person1 = new person('Mick');
   person1.getName(); //Mick

从这个例子可以看出,通过给 Person.prototype 设置了一个函数对象的属性,那有 Person 的实例(person1)出来的普通对象就继承了这个属性。具体是怎么实现的继承,就要讲到下面的原型链了。

小问题,上面两个 this 都指向谁?

 var person1 = new person('Mick');
 person1.name = 'Mick'; // 此时 person1 已经有 name 这个属性了
 person1.getName(); //Mick

故两次 this 在函数执行时都指向 person1。

推荐教程:《JS教程

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
Article précédent:Ajax reçoit des données JSONArticle suivant:Ajax reçoit des données JSON