Maison > Article > interface Web > Une brève analyse de la relation entre __proto__ et prototype en JavaScript
Cette fois, je vais vous donner une brève analyse de la relation entre __proto__ et prototype en JavaScript. Ce qui suit est un cas pratique. Suivez l'éditeur pour y jeter un œil.
1. Le __proto__ de tous les constructeurs/fonctions pointe vers Function.prototype, qui est une fonction vide (Vide function)
Number.__proto__ === Function.prototype // true Boolean.__proto__ === Function.prototype // true String.__proto__ === Function.prototype // true Object.__proto__ === Function.prototype // true Function.__proto__ === Function.prototype // true Array.__proto__ === Function.prototype // true RegExp.__proto__ === Function.prototype // true Error.__proto__ === Function.prototype // true Date.__proto__ === Function.prototype // true
Il y a un total de 12 constructeurs/objets intégrés (intégrés) en JavaScript (JSON est nouvellement ajouté dans ES5). Voici 8 constructeurs accessibles. Le reste comme Global n'est pas accessible directement, les arguments ne sont créés par le moteur JS que lorsque la fonction est appelée, Math et JSON existent sous forme d'objets et n'en nécessitent pas de nouveaux. Leur __proto__ est Object.prototype. Comme suit
Math.__proto__ === Object.prototype // true JSON.__proto__ === Object.prototype // true
Les "tous les constructeurs/fonctions" mentionnés ci-dessus incluent certainement ceux personnalisés. Comme suit
// 函数声明 function Person() {} // 函数表达式 var Man = function() {} console.log(Person.__proto__ === Function.prototype) // true console.log(Man.__proto__ === Function.prototype) // true
Qu'est-ce que cela signifie ?
Tous les constructeurs proviennent de Function.prototype, même le constructeur racine Object et Function lui-même. Tous les constructeurs héritent des propriétés et méthodes de Function.prototype. Tels que la longueur, l'appel, l'application, la liaison (ES5).
Function.prototype est également le seul type de XXX.prototype est prototype de « fonction ». Le prototype des autres constructeurs est un objet. Par exemple :
console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object console.log(typeof Object.prototype) // object
Oh, il est également mentionné ci-dessus qu'il s'agit d'une fonction vide, jetons un œil à alert(Function.prototype).
Maintenant que nous savons que le __proto__ de tous les constructeurs (y compris ceux intégrés et personnalisés) est Function.prototype, alors qui est le __proto__ de Function.prototype ?
Je crois que vous avez tous entendu dire que les fonctions en JavaScript sont également des citoyens de premier ordre, alors comment pouvez-vous le montrer ? Comme indiqué ci-dessous
console.log(Function.prototype.__proto__ === Object.prototype) // true
Cela montre que tous les constructeurs sont également des objets JS ordinaires et que des attributs peuvent être ajoutés/supprimés au constructeur. En même temps, il hérite également de toutes les méthodes d'Object.prototype : toString, valueOf, hasOwnProperty, etc.
Qui est le __proto__ d'Object.prototype ?
Object.prototype.__proto__ === null // true
a atteint le sommet et est nul.
2. Le __proto__ de tous les objets pointe vers le prototype de son constructeur
Ce qui précède teste le __proto__ de tous les constructeurs intégrés et personnalisés, comme suit. regardez à qui pointe le __proto__ des objets d'instance de tous ces constructeurs ?
Regardez d'abord le constructeur intégré du moteur JavaScript
var obj = {name: 'jack'} var arr = [1,2,3] var reg = /hello/g var date = new Date var err = new Error('exception') console.log(obj.__proto__ === Object.prototype) // true console.log(arr.__proto__ === Array.prototype) // true console.log(reg.__proto__ === RegExp.prototype) // true console.log(date.__proto__ === Date.prototype) // true console.log(err.__proto__ === Error.prototype) // true
Regardez ensuite le constructeur personnalisé, ici une personne est définie
function Person(name) { this.name = name } var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true
p est Person Pour les objets d'instance, le prototype interne de p pointe toujours vers le prototype de son constructeur Person.
Chaque objet a un attribut constructeur et son constructeur peut être obtenu, donc les résultats imprimés suivants sont également identiques
function Person(name) { this.name = name } var p = new Person('jack') console.log(p.__proto__ === p.constructor.prototype) // true
La personne ci - dessus n'ajoute pas d'attributs ou de méthodes à son prototype , ajoutez ici une méthode getName
function Person(name) { this.name = name } // 修改原型 Person.prototype.getName = function() {} var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // true
à son prototype. Vous pouvez voir que p.__proto__, Person.prototype et p.constructor.prototype sont tous identiques, c'est-à-dire qu'ils pointent tous vers le même objet. .
Si vous définissez le prototype d'une autre manière, le résultat sera quelque peu différent
function Person(name) { this.name = name } // 重写原型 Person.prototype = { getName: function() {} } var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // false
Person.prototype est directement réécrit ici (remarque : l'exemple précédent consiste à modifier le prototype). Le résultat montre que p.__proto__ pointe toujours vers Person.prototype, et non vers p.constructor.prototype.
C'est également facile à comprendre. Ce qui est attribué à Person.prototype est un littéral d'objet {getName : function(){}}, le constructeur d'un objet défini à l'aide de la méthode littérale d'objet pointe vers le constructeur racine Object, Object.prototype est un objet vide {}, {} est naturellement identique à {getName : function(){}} n'est pas égal. Comme suit
var p = {} console.log(Object.prototype) // 为一个空的对象{} console.log(p.constructor === Object) // 对象直接量方式定义的对象其constructor为Object console.log(p.constructor.prototype === Object.prototype) // 为true,不解释
Le __proto__ utilisé dans le code ci-dessus n'est actuellement pas pris en charge dans IE6/7/8/9. Dans IE9, vous pouvez utiliser Object.getPrototypeOf(ES5) pour obtenir le prototype interne d'un objet.
var p = {} var __proto__ = Object.getPrototypeOf(p) console.log(__proto__ === Object.prototype) // true
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!