Maison > Article > interface Web > Vu sous cet angle, les prototypes et les chaînes de prototypes ne semblent pas difficiles.
La colonne
javascript présente brièvement et clairement les prototypes et les chaînes de prototypes.
En JavaScript, prototype et chaîne de prototypes sont des concepts inévitables et importants, alors comment comprendre le prototype et la chaîne de prototypes ? Ce qui suit est ma compréhension et mon résumé des prototypes et des chaînes de prototypes. Peut-être qu'une partie de la compréhension est encore relativement superficielle. À mesure que le temps passe et que la compréhension s'approfondit, d'autres seront ajoutées à l'avenir. Si vous trouvez qu'il y a quelque chose qui ne va pas dans ma compréhension, n'hésitez pas à me corriger dans les commentaires.
Dans le processus d'apprentissage passé, nous avons appris du langage orienté objet Java qu'il comporte trois éléments : l'encapsulation et héritage, polymorphisme. Concernant l’héritage, java et javascript ne sont en réalité pas exactement identiques.
Alors, comment est conçu le javascript ? Au début, les navigateurs ne pouvaient que parcourir le contenu Web, mais ne pouvaient pas interagir avec l'utilisateur. Autrement dit, lorsque nous saisissions notre compte et notre mot de passe pour nous connecter, le navigateur ne pouvait pas juger le contenu saisi. le serveur. Afin de résoudre le problème, Netscape Pour ce problème, inventez un langage de script auxiliaire utilisé avec Java et dont la syntaxe est quelque peu similaire. On peut voir que javascript est affecté par java. S'il y a des objets, le mécanisme d'héritage sera impliqué. Alors, quel est le mécanisme d'héritage de JS ?
JS fait référence à la conception de Java et utilise l'opérateur new pour générer des objets, mais la différence avec Java est que new est suivi de Construtor au lieu de Class.
// java 中生成一个对象 Person p = new Person() // Person 指的是类名 // js 生成一个对象 function Person (age) { this.age = age this.nation = 'China' } var father = new Person(42) // Person 指的是构造函数 var mingming = new Person(11)复制代码
Le constructeur est également une fonction ordinaire, et il a également un attribut prototype. La différence avec les fonctions ordinaires est qu'il nécessite que la première lettre soit en majuscule. Si le constructeur est appelé à l'aide de l'opérateur new, il doit effectuer quatre étapes :
1. Créer un nouvel objet
2. Pointez ceci vers ce nouvel objet
3. Exécutez le constructeur et ajoutez des attributs et des méthodes au nouvel objet
4. Renvoyez ce nouvel objet
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana')复制代码
Toute fonction a une propriété prototype, qui pointe vers l'objet prototype. Alors le prototype est en fait un objet. Les propriétés définies sur le prototype, par héritage (implémenté par l'opérateur new), l'objet instancié possède également cette propriété.
La relation entre le prototype et le constructeur : il existe une propriété de prototype dans le constructeur, via laquelle le prototype est accessible.
En prenant le code du constructeur comme exemple, Food est le constructeur, Food.prototype est le prototype et food est un objet généré en faisant référence à Food.prototype.
L'instance fait référence à un constructeur qui crée des propriétés et des méthodes qui peuvent être « héritées » sur le prototype et est créé via l'opérateur new. objet.
En termes simples, nous utilisons l'opérateur new pour créer une instance de nourriture, et nous pouvons utiliser instanceof pour vérifier la relation entre l'instance et le constructeur.
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 实例化 var res = food instanceof Food // 检查 food 是否为 Food 实例 console.log(res) // true复制代码
Lorsque nous définissons une propriété sur le prototype, l'instance "héritera" également de cette propriété.
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 实例化 var res = food instanceof Food // 检查 food 是否为 Food 实例 console.log(res) // true // 原型定义属性 Food.prototype.type = 'object named Food' var foodRes = food.type // 实例继承的属性 console.log(foodRes) // object named Food复制代码
Tout objet aura un attribut __proto__ lors de sa création, qui pointe vers l'objet prototype du constructeur qui a généré l'objet actuel. Étant donné que cet attribut n'est pas un attribut standard, ne modifiez pas la valeur de cet attribut avec désinvolture pour éviter d'endommager la chaîne de prototypes. Autrement dit, les instances peuvent accéder au prototype via l'attribut __proto__.
对象中的 __proto__ 属性在所有实现中是无法访问到的,但是可以通过 isPrototypeOf() 方法来确定对象之间是否存在着这种关系。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 实例化 console.log(food.__proto__ === Food.prototype) // true console.log(Food.prototype.isPrototypeOf(food)) // true复制代码
构造函数可以通过 prototype 属性访问到原型,那么原型也是能够通过某种途径访问到构造函数的,其就是原型中的一个属性 constructor ,该属性并不是真正的构造函数,真正的构造函数是指 Constructor,两者不要混淆了。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') console.log(Food.prototype.constructor === Food) //true复制代码
关键:prototype 的 constructor 指向构造函数本身
那么构造函数、原型、实例三者的关系应该是这样的:
为了更好地理解这一过程,我通过一个故事给大家梳理一下:
1. 很久以前,有个雕刻家偶然看到一个很精致的花瓶(原型 Food.prototype)
2. 一天,他想通过大批生产复刻这个花瓶来发家致富,于是他先分析这个花瓶,还原了雕刻的过程,并设计出了一条生产线(构造器 Food)
3. 然后通过这条生产线,雕刻出许许多多的复刻花瓶。(实例 food)
proto 是任何对象都有的属性,在js中会形成一条 proto 连接起来的链条,递归访问 proto 直到值为 null ,这个搜索过程形成的链状关系就是原型链。
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana') // 实例化 // 原型链 console.log(food.__proto__) // Food {} console.log(food.__proto__.__proto__) // {} console.log(food.__proto__.__proto__.__proto__) // null复制代码
如下图:
1. 每创建一个函数都会有一个 prototype 属性,该属性是一个指针,指向一个对象,该对象为原型对象(Food.prototype)。
2. 原型对象上的默认属性 constructor 也是一个指针,指向其相关的构造函数。
3. 通过 new 操作符产生的实例对象都会有一个内部属性指向原型对象,该实例对象可以访问原型对象上的所有属性和方法。
4. 实例可以通过内部指针访问到原型对象,原型对象也可以通过 constructor 找到构造函数。
5. 每个构造函数都有一个原型对象,原型对象上包含一个指向构造函数的指针,实例包含一个指向原型对象的内部指针。
6. __proto___ 的指向取决于对象创建时的实现方式。
7. 构造函数实例,封装的函数,如果通过 new 操作符来调用则是构造函数,否则则不是。 8. 在整个原型链上寻找某个属性,对性能有影响,越是上层的原型对象,对性能的影响越大。
9. js中一切皆对象,通过 new Function 的是函数对象,其构造函数是 Function,而普通对象的构造函数则是 Object 。
10. 每一个对象都有 __proto__ 属性,而每一个函数对象才有 prototype 属性。
1.《JavaScript 高级程序设计》
2.developer.mozilla.org/zhCN/docs/W…
如果你仔细阅读完本文,相信你对 JavaScript 中的原型和原型链会有新的认识。如果你觉得对你有帮助,记得 点赞 哦!如果你发现我理解的有问题,也欢迎你在评论中指正出来。
相关免费学习推荐: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!