原型和原型鏈

2021-10-14 07:46:08 字數 3300 閱讀 7290

首先,在 js 中可以使用類或建構函式來建立乙個例項:

function

person()

// or

class

person

person.prototype.name =

'kevin'

;let p1 =

newperson()

;let p2 =

newperson()

;// p1.name === p2.name = 'kevin';

每個函式/類都有乙個prototype屬性,它指向了乙個物件,這個物件就是我們呼叫這個建構函式/類而建立的例項的原型,即上面**中p1p2的原型。

原型可以這樣理解:每乙個 js 物件(null除外)在建立的時候就會與之關聯另乙個物件,這個物件就是我們所說的原型,每乙個物件都會從原型中 「繼承」 屬性

用一張圖來表示建構函式和例項原型之間的關係:

__proto__這個屬性,它指向該物件的原型。

如:

p1.__proto__ === person.prototype;

let n =3;

n.__proto__ === number.prototype;

因此關係圖更新為:

__proto_屬性來獲取例項的原型之外,還能使用object.getprototypeof(p1)(es5 的方法)來獲取物件原型:

object.

getprototypeof

(p1)

=== person.prototype;

每個原型都有乙個constructor屬性來指向與其關聯的建構函式/類。

如:

person.prototype.constructor === person;

number.prototype.constructor === number;

因此再次更新關係圖:

原型也是乙個物件,因此我們可以使用最原始的方式建立它:

let obj =

newobject()

;

其實原型物件也就是通過object建構函式生成的,因此原型物件的__proto__屬性會指向建構函式的prototype,也就是:

p1.__proto__.__proto__ === object.prototype;

// 即

person.prototype.__proto__ === object.prototype;

那麼object.prototype的原型是什麼呢?

答案是nullobject.prototype.__proto__ === null

代表了原型鏈的盡頭。

因此關係圖可以更新為:其中由相互關聯的原型組成的鏈狀結構就是原型鏈,也就是藍色的這條線。

null為止。

如:

object.prototype.name =

'end'

;function

person()

person.prototype.name =

'kevin'

;let p =

newperson()

;p.name =

'daisy'

;// 首先會在當前物件中查詢

console.

log(p.name)

;// daisy

// 若找不到,則去與其關聯的原型中查詢

delete p.name;

console.

log(p.name)

;// kevin

// 若其原型中也沒有,則去原型的原型中查詢

delete person.prototype.name;

console.

log(p.name)

;// end

先看個例子:

function

person()

let person =

newperson()

;person.constructor === person;

//true

根據我們前面的描述,constructorperson物件的原型中的屬性,person中並沒有這個屬性;但當我們獲取person.constructor時,會從person的原型中讀取,而原型中正好有這個屬性,因此還是能夠正確讀取。

因此:

person.constructor === person.prototype.constructor;
絕大部分瀏覽器都支援這個非標準的方法來訪問原型,然而它並不存在於person.prototype中,實際上,它是來自於object.prototype,與其說是乙個屬性,不如說是乙個getter/setter,當使用obj.__proto__時,可以理解為返回了object.getprototypeof(obj)

前面有說到,每乙個物件都會從原型中 「繼承」 屬性。實際上,繼承是乙個比較迷惑的說法,在 《你不知道的 js》 中有這樣一段話:

繼承意味著複製操作,然而 js 預設並不會複製物件中的屬性,相反,js 只是在兩個物件之間建立乙個關聯,這樣,乙個物件就可以通過委託訪問另乙個物件的屬性和函式。

所以與其叫繼承,委託的說法反而更準確些。

ref:

原型 和 原型鏈

每乙個js物件 null除外 都和另乙個物件相關聯。另乙個 物件就是我們熟知的原型,每乙個物件都從原型繼承屬性。所有通過物件直接量建立的物件都具有同乙個原型物件,並可以通過js object.prototype 獲得對原型物件的引用。通過關鍵字new和構造函式呼叫建立的物件的原型就是建構函式的 pr...

原型和原型鏈

原型鏈 例項物件與原型之間的連線,叫做原型鏈 function human human.prototype.age 22 var a new human console.log a.age 這裡的age掛載到了human的原型上面了。其實原型就是乙個物件。a為什麼能找到原型上面的物件呢?這裡例項物件...

原型和原型鏈

建構函式 function foo name age function 其實是 var a new object 的語法糖 var a 其實是 var a new array 的語法糖 function foo 其實是 var foo new function 的語法糖 new乙個物件的過程 建立乙...