Heim  >  Artikel  >  Web-Frontend  >  So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

coldplay.xixi
coldplay.xixinach vorne
2020-10-22 18:30:341675Durchsuche

In der Kolumne

Javascript werden Prototypen und Prototypenketten einfach und übersichtlich vorgestellt.

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

In JavaScript sind Prototyp und Prototypkette unvermeidliche und wichtige Konzepte. Wie versteht man also Prototyp und Prototypkette? Das Folgende ist mein Verständnis und meine Zusammenfassung von Prototypen und Prototypketten. Vielleicht ist ein Teil des Verständnisses noch relativ oberflächlich. Mit der Zeit und dem Vertiefen des Verständnisses werden in Zukunft weitere hinzugefügt. Wenn Sie feststellen, dass mit meinem Verständnis etwas nicht stimmt, können Sie mich gerne in den Kommentaren korrigieren.

1. Warum ist JavaScript als prototypbasiertes Modell konzipiert?

Im vergangenen Lernprozess haben wir von der objektorientierten Sprache Java gelernt, dass sie drei Elemente enthält: Kapselung, Vererbung und Polymorphismus. Was die Vererbung betrifft, sind Java und Javascript eigentlich nicht genau dasselbe.
Wie ist also Javascript gestaltet? Früher konnten Browser nur Webinhalte durchsuchen, aber keine Benutzerinteraktion durchführen. Das heißt, wenn wir unser Konto und Passwort zum Anmelden eingaben, konnte der Browser den eingegebenen Inhalt nicht beurteilen Um das Problem zu lösen, erfindet Netscape für dieses Problem eine Hilfsskriptsprache, die mit Java verwendet wird und in der Syntax etwas ähnlich ist. Daraus ist ersichtlich, dass Javascript von Java beeinflusst wird. Wenn es Objekte gibt, ist der Vererbungsmechanismus beteiligt.
        JS bezieht sich auf das Design von Java und verwendet den New-Operator zum Generieren von Objekten. Der Unterschied zu Java besteht jedoch darin, dass auf New Construtor und nicht Class folgt.

// 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)复制代码

2. Konstruktor

Der Konstruktor ist ebenfalls eine gewöhnliche Funktion und verfügt auch über ein Prototypattribut. Der Unterschied zu gewöhnlichen Funktionen besteht darin, dass der erste Buchstabe großgeschrieben werden muss. Wenn der Konstruktor mit dem neuen Operator aufgerufen wird, muss er vier Schritte ausführen:
  1. Ein neues Objekt erstellen
    2. Richten Sie dies auf dieses neue Objekt
 ​ 3. Führen Sie den Konstruktor aus und fügen Sie Eigenschaften und Methoden zum neuen Objekt hinzu
       4. Dieses neue Objekt zurückgeben

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')复制代码

3. Prototyp-Prototyp

Jede Funktion hat eine Prototyp-Eigenschaft, die auf das Prototyp-Objekt zeigt. Dann ist der Prototyp tatsächlich ein Objekt. Durch Vererbung (implementiert durch den neuen Operator) verfügt das instanziierte Objekt auch über diese Eigenschaft.
        Die Beziehung zwischen Prototyp und Konstruktor: Im Konstruktor gibt es eine Prototyp-Eigenschaft, über die auf den Prototyp zugegriffen werden kann.

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

Nehmen wir den Code im Konstruktor als Beispiel: Food ist der Konstruktor, Food.prototype ist der Prototyp und Food ist ein Objekt, das durch Verweis auf Food.prototype generiert wird. St4. Instanz

Instanz bezieht sich auf einen Konstruktor, der die Attribute und Methoden erstellt hat, die vom Prototyp „erben“ können, und der vom neuen Operator erstellt wurde. So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

                                                                                                                                                               Wir verwenden den neuen Operator, um eine Food-Instanz zu erstellen, und wir können „instanceof“ verwenden, um die Beziehung zwischen der Instanz und dem Konstruktor zu überprüfen.

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复制代码

Wenn wir eine Eigenschaft auf dem Prototyp definieren, „erbt“ die Instanz diese Eigenschaft auch. So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

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复制代码
5. Impliziter Prototyp _

_proto__

Jedes Objekt verfügt beim Erstellen über ein _

_proto__-Attribut, das auf das Prototypobjekt des Konstruktors verweist, der das aktuelle Objekt generiert hat. Da es sich bei diesem Attribut nicht um ein Standardattribut handelt, sollten Sie den Wert dieses Attributs nicht beiläufig ändern, um eine Beschädigung der Prototypenkette zu vermeiden. Das heißt, Instanzen können über das Attribut __proto__

auf den Prototyp zugreifen.

        对象中的 __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复制代码

6. 构造函数 constructor

        构造函数可以通过 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复制代码

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

        关键:prototype 的 constructor 指向构造函数本身    

        那么构造函数、原型、实例三者的关系应该是这样的:

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

         为了更好地理解这一过程,我通过一个故事给大家梳理一下:
       1. 很久以前,有个雕刻家偶然看到一个很精致的花瓶(原型 Food.prototype)
       2. 一天,他想通过大批生产复刻这个花瓶来发家致富,于是他先分析这个花瓶,还原了雕刻的过程,并设计出了一条生产线(构造器 Food)
       3. 然后通过这条生产线,雕刻出许许多多的复刻花瓶。(实例 food)

7. 原型链

         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复制代码

        如下图:

So gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.

总结

        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(视频)

Das obige ist der detaillierte Inhalt vonSo gesehen scheinen Prototypen und Prototypenketten nicht schwierig zu sein.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen