JavaScript中原型和原型鏈

原型[prototype]:函數

爲其餘對象提供共享屬性的對象。this

每一個函數都有一個原型(prototype)屬性,這個屬性是一個指針,指向一個對象,這個對象包含特定實例共享的一些屬性和方法。spa

 

以例服人:prototype

這個例子說明了原型對象是共享的,而且是一個指針,而且對象的實例中也有指向prototype指向對象的指針。指針

function Animal(name) { this.name = name || "動物"; } Animal.prototype.runs = function() { console.log(this.name + ',跑起來了\n') } var dog = new Animal('小狗') dog.runs() //輸出"小狗跑起來了"

// 下面增長的方法,dog對象可使用嗎?
Animal.prototype.hi = function() {console.log('hi')} dog.hi() //輸出"hi",說明原型屬性是一個指針,指向一個共享對象,無論先添加的仍是後添加的方法都能調用

//dog做爲一個Animal實例,他的__proto__屬性和Animal.prototype指向同一個對象,因此纔可使用原型的方法。
console.dir(dog) // 查看 dog.__proto__

// dog.__proto__ & Animal.prototype
console.log(dog.__proto__ === Animal.prototype) //true,有相同的指針地址

 

原生構造函數的原型對象[不單函數有原型對象]code

console.dir(Object.prototype)對象

console.dir(Array.prototype)blog

console.dir(String.prototype)繼承

console.dir(Date.prototype)原型鏈

 

再看一個__proto__  &  prototype的例子

var obj = { } obj.toString() // "[object Object]"
 //obj 對象爲何有 toString 方法? //由於 obj 對象是 Object 構造函數的實例,obj 對象的原型指針指向 Object.prototype 對象。console.log(obj.__proto__ === Object.prototype )

經過原型關係圖理解:

 

再看一個函數的原型的例子

var obj = {name: 'jack'} function getName() { console.log(this.name) } // 問題:Animal.call 方法來自哪?
getName.call(obj)  //來自Function對象
 console.dir(getName) console.log(getName.__proto__ === Function.prototype)  //true
console.log(Function.prototype.__proto__  === Object.prototype)  //true

經過原型關係圖理解

原型繼承:

function Animal() { this.name = '動物' } Animal.prototype.runs = function() { console.log(this.name + ',跑起來了\n') return this } function Bird() { this.name = '鳥' } Bird.prototype = new Animal() //讓Bird的原型等於Animal的實例,由於new Animal中有__proto__指向Animal.prototype的指向(沿着原型鏈尋找),此處也能夠寫爲Bird.prototype = Animal.prototype Bird.prototype.fly = function() { console.log(this.name + ',飛走了\n') return this } function Crow(name) { this.name = name || '烏鴉' } Crow.prototype = new Bird() Crow.prototype.drink = function() { console.log(this.name + ',喝飽了水\n') return this } var crow = new Crow('一隻可愛的小烏鴉') crow.drink().runs().fly() console.dir(crow)

輸出結果:

 

 

原型總結:

每個構造函數都有一個和其對應的原型對象。

構造函數的 prototype 屬性和其實例對象的 「__proto__」 屬性指向同一個對象。

某構造函數的全部實例對象,共享一份原型對象。

全部的對象均可以經過 「__proto__」 屬性,最終鏈接到 Object.prototype 對象。

構造函數用 prototype 來定義原型的屬性和方法,實例對象用 「__proto__」 來查找原型的屬性和方法。

當查找一個對象的屬性或方法時,JS引擎會向上遍歷其原型鏈,直到找到給定名稱的屬性爲止。若是最終在 Object.prototype 對象仍然沒有找到此屬性或方法,則返回 undefined 值。

相關文章
相關標籤/搜索