顯示原型和隱式原型,手繪原型鏈,原型鏈是什麼?為什麼要有原型鏈
顯式原型:prototype
隱式原型:__proto__
1. 每個函式function都有一個prototype,即顯式原型(屬性)
2. 每個例項物件都有一個__proto__,可稱為隱式原型(屬性)
3. 物件的隱式原型的值為其對應建構函式的顯式原型的值
4. 總結:
* 物件的__proto__屬性: 建立物件時自動新增的, 預設值為建構函式的prototype屬性值
*Object.prototype的__proto__屬性指向null。
區別:
__proto__是每個物件都有的一個屬性,而prototype是函式才會有(函式也有__proto__)的屬性。__proto__指向的是當前物件的原型物件,而prototype指向它的建構函式的原型物件。
作用:
在js中萬物皆物件,方法(Function)是物件,方法的原型(Function.prototype)是物件,物件具有屬性(__proto__)稱為隱式原型,物件的隱式原型指向構造該物件的建構函式的顯式原型。
- //定義建構函式
- function Fn() { // 內部語句: this.prototype = {}
- }
- // 1. 每個函式function都有一個prototype,即顯式原型屬性, 預設指向一個空的Object物件
- console.log(Fn.prototype)
- // 2. 每個例項物件都有一個__proto__,可稱為隱式原型
- //建立例項物件
- var fn = new Fn() // 內部語句: this.__proto__ = Fn.prototype
- console.log(fn.__proto__)
- // 3. 物件的隱式原型的值為其對應建構函式的顯式原型的值
- console.log(Fn.prototype===fn.__proto__) // true
- //給原型新增方法
- Fn.prototype.test = function () {
- console.log('test()'
- }
- //通過例項呼叫原型的方法
- fn.test()
- 建構函式的顯示原型的隱式原型:
- 內建物件(built-in object):比如Array(),Array.prototype.__proto__指向什麼?Array.prototype也是一個物件,物件就是由 Object() 這個建構函式建立的,因此Array.prototype.__proto__ === Object.prototype //true,或者也可以這麼理解,所有的內建物件都是由Object()建立而來。
- 自定義物件
function Foo(){} var foo = new Foo() Foo.prototype.__proto__ === Object.prototype //true 理由同上
Foo.prototype===foo._proto_ //true
2. 其他情況: (1)
function Bar(){} //這時我們想讓Foo繼承Bar Foo.prototype = new Bar() Foo.prototype.__proto__ === Bar.prototype //true(2)
//我們不想讓Foo繼承誰,但是我們要自己重新定義Foo.prototype
Foo.prototype = { a:10, b:-10 } //這種方式就是用了物件字面量的方式來建立一個物件,根據前文所述 Foo.prototype.__proto__ === Object.prototype
注: 以上兩種情況都等於完全重寫了Foo.prototype,所以Foo.prototype.constructor也跟著改變了,於是乎constructor這個屬性和原來的建構函式Foo()也就切斷了聯絡。
- 建構函式的隱式原型
既然是建構函式那麼它就是Function()的例項,因此也就指向Function.prototype,比如 Object.__proto__ === Function.prototype
手繪原型鏈
原型鏈是什麼
實現繼承主要依賴原型鏈。
什麼是原型物件。我們知道每個建構函式一旦建立都有prototype指標指向它的原型物件(建構函式.prototype)。而原型物件(建構函式.prototype)會預設生成一個constructor指標又指向建構函式。在建立例項時,例項有一個內部屬性[[prototype]]指向該原型物件。原型物件內建立的所有方法會被所有例項共享。
原型是什麼?
在JavaScript中原型是一個prototype物件,用於表示型別之間的關係。
什麼是原型鏈。
JavaScript萬物都是物件,物件和物件之間也有關係,並不是孤立存在的。物件之間的繼承關係,在JavaScript中是通過prototype物件指向父類物件,直到指向Object物件為止,這樣就形成了一個原型指向的鏈條,專業術語稱之為原型鏈。
原型鏈就是建立一個建構函式,它會預設生成一個prototype屬性並指向原型物件。使用下一個建構函式的原型物件作為這個建構函式的例項。即 nextFuction.prototype = new thisFuction();
在下下一個建構函式的原型物件 = new nextFuction。這樣下去就會構成一條例項與原型之間的鏈條,這就是原型鏈。
為什麼要有原型鏈
建構函式的所有例項都可以訪問建構函式原型中的方法和屬性。
也就是把共有的東西統一存放到一個共享空間。這樣可以避免相同函式重複宣告,減少空間佔用,節省記憶體。實現繼承,子類繼承父類的方法和變數;
原型上可以定義一些方法和變數;
以這個原型建立的物件,可以使用原型方法和變數,從而實現繼承。