- 例項物件
- 原型物件
- 物件原型
- 短暫總結一下
- constructor
- 原型鏈
何為原型鏈呢?
就是例項物件和原型物件之間的連結,每一個物件都有原型,原型本身又是物件,原型又有原型,以此類推形成一個鏈式結構.稱為原型鏈。
這裡又扯到了另外兩個概念了。
例項物件>>> 先往下看例項物件
原型物件>>> 先往下看 原型物件
例項物件
說到這裡。我們另外再來提一提 另一個東西: 建構函式。那既然提到了建構函式 由不得不提普通函式了。
先來講一下建構函式
建構函式是一種特殊的函式,主要用來初始化物件,即為物件成員變數賦初始值。
例如:
let Num = function Num() {
this.add = function (a, b) {
return a + b
}
}
let n = new Num()
console.log(n.add(1, 2));
這裡例項物件已經出來了。就是在你new 這個 建構函式的時候。就已經建立了例項物件 在本文中 n就是一個例項物件
**這裡簡單說一下例項物件在建立成功時會發生什麼變化。
- 在記憶體中建立一個新的空物件;
- 讓this指向這個新的物件。這裡this指向問題 我只用一句話就能總結: 誰呼叫this就指向誰
- 執行建構函式里面的程式碼,給這個新物件新增屬性和方法;
- 返回這個新物件(所以建構函式里面不需要return)。
再來講一下普通函式
普通函式就是.... 就是最普通的函式 例如
function add(a, b) { return a+b };
add(1,2)
雖然上述兩種方式。都能得到結果 3
但是兩種宣告以及使用的方式都不一樣。
那這裡總結下區別
- 建構函式首字母要大寫,類似於python中的類
- 建構函式是透過new運算子來建立例項物件的,而普通函式則不需要。
這裡還有個點。
例項物件建立成功後 已經有了一個__proto__的內建屬性了。
而建構函式本身有個屬性是prototype 稱之為物件原型
原型物件
原型物件是建構函式上的一個屬性,用來建立公共的方法。也就是prototype
舉個例子。
直接建立個建構函式。然後賦值個方法。
//語法: 建構函式.prototype.方法名 = function() {}
function Animal(name) {
this.name = name
}
// 賦值公共方法
Animal.prototype.eat = function () {
console.log(`${this.name}在吃飯`)
}
let dog = new Animal("狗")
let cat = new Animal("貓")
dog.eat()
cat.eat()
console.log(dog.eat === cat.eat) // true
結果
狗在吃飯
貓在吃飯
true
這裡扯到了 原型物件 那就再講講另一個概念 物件原型。其實這個概念可以忽略不計。
物件原型
**物件原型是例項物件(物件)身上的一個屬性, 該屬性為 _proto_ **
//語法: 建構函式.prototype.方法名 = function() {}
function Animal(name) {
this.name = name
}
// 賦值公共方法
Animal.prototype.eat = function () {
console.log(`${this.name}在吃飯`)
}
let dog = new Animal("狗");
console.log(dog.__proto__);
console.log(dog.__proto__ === Animal.prototype);
結果
{ eat: [Function (anonymous)] }
true
短暫總結一下
這裡捋一下關係
- 每個建構函式都有一個原型物件 原型物件的(
prototype
) __proto__
等於其建構函式的prototype
,即每個__proto__
都指向其建構函式的prototype
- 原型物件(prototype) == 物件原型(__proto__)
constructor
construct是原型物件(prototype) 和 物件原型(__proto__)身上的一個屬性
而 constructor會記錄當前物件屬於哪個建構函式。
這裡舉個例子吧、
//語法: 建構函式.prototype.方法名 = function() {}
function Animal(name) {
this.name = name
}
// 賦值公共方法
Animal.prototype.eat = function () {
console.log(`${this.name}在吃飯`)
}
let dog = new Animal("狗");
dog.constructor.prototype
console.log(dog.constructor.prototype)
結果 這裡在node中看不出來。我們直接看瀏覽器中的
這裡就很好理解了。
其實 constructor
的出現原本就是用來進行物件型別判斷。任何物件都有constructor
屬性。
那你說這個有啥用???
因為我們是搞爬蟲的嗎。肯定是很有用的。
constructor 本來就是用來找到其上層建構函式的。那我們在設定補環境框架。或者是在補環境的時候不就能容易找到最外層的構造環境了嗎?
原型鏈
很好現在基礎概念都懂了。那我們是不是可以重新梳理了一下呢?
我的理解是原型鏈的構成包含了上文我講的的這些部分。
所謂原型鏈的流程(僅本人在補環境中的理解):
當你在尋找一個方法或者屬性。如果該物件自身沒有這個屬性 或者方法。
那這個引擎(JS)就會沿著原型鏈向上去找。直到找到這個屬性 或者方法。
直到到達原型鏈的最頂層也就是我們上文說的Prototype
那話說到這裡。
說白了 原型鏈其實就是JavaScript中用於實現物件繼承的一種機制。
好了 此文完結。懂各種概念就行