深入javascript之原型和原型鏈

2021-08-31 13:43:21 字數 3225 閱讀 6025

所有引用型別(函式,陣列,物件)都擁有__proto__屬性(隱式原型)

所有函式擁有prototype屬性(顯式原型)(僅限函式)

原型物件:擁有prototype屬性的物件,在定義數時就被建立

先複習下建構函式

//建立建構函式

function word(words)

word.prototype =

}//建立例項

var w = new word("hello world");

w.print = function()

w.print();  //hello world

w.alert();  //hello world

print()方法是w例項本身具有的方法,所以w.print()列印hello world;alert()不屬於w例項的方法,屬於建構函式的方法,w.alert()也會列印hello world,因為例項繼承建構函式的方法。

例項w的隱式原型指向它建構函式的顯式原型,指向的意思是恆等於

w.__proto__ === word.prototype
當呼叫某種方法或查詢某種屬性時,首先會在自身呼叫和查詢,如果自身並沒有該屬性或方法,則會去它的__proto__屬性中呼叫查詢,也就是它建構函式的prototype中呼叫查詢。所以很好理解例項繼承建構函式的方法和屬性:

w本身沒有alert()方法,所以會去word()的顯式原型中呼叫alert(),即例項繼承建構函式的方法。         

function.prototype.a = "a";

object.prototype.b = "b";

function person(){}

console.log(person);    //function person()

let p = new person();

console.log(p);         //person {} 物件

console.log(p.a);       //undefined

console.log(p.b);       //b

想一想p.a列印結果為undefined,p.b結果為b

解析:p是person()的例項,是乙個person物件,它擁有乙個屬性值__proto__,並且__proto__是乙個物件,包含兩個屬性值constructor和__proto__

console.log(p.__proto__.constructor);   //function person(){}

console.log(p.__proto__.__proto__);     //物件{},擁有很多屬性值

我們會發現p.__proto__.constructor返回的結果為建構函式本身,p.__proto__.__proto__有很多引數

我們呼叫constructor屬性,p.___proto__.__proto__.constructor得到擁有多個引數的object()函式,person.prototype的隱式原型的constructor指向object(),即person.prototype.__proto__.constructor == object()

從p.__proto__.constructor返回的結果為建構函式本身得到person.prototype.constructor == person()所以p.___proto__.__proto__== object.prototype 

所以p.b列印結果為b,p沒有b屬性,會一直通過__proto__向上查詢,最後當查詢到object.prototype時找到,最後列印出b,向上查詢過程中,得到的是object.prototype,而不是function.prototype,找不到a屬性,所以結果為undefined,這就是原型鏈,通過__proto__向上進行查詢,最終到null結束

console.log(p.__proto__.__proto__.__proto__);   //null

console.log(object.prototype.__proto__);        //null

大家理解剛才的過程,相信下面這些應該也都明白

//function

function function(){}

console.log(function);  //function()

console.log(function.prototype.constructor);    //function()

console.log(function.prototype.__proto__);      

console.log(function.prototype.__proto__.__proto__);    //null

console.log(function.prototype.__proto__.constructor);  //object()

console.log(function.prototype.__proto__ === object.prototype); //true

總結:1.查詢屬性,如果本身沒有,則會去__proto__中查詢,也就是建構函式的顯式原型中查詢,如果建構函式中也沒有該屬性,因為建構函式也是物件,也有__proto__,那麼會去它的顯式原型中查詢,一直到null,如果沒有則返回undefined

2.p.__proto__.constructor  == function person(){}

3.p.___proto__.__proto__== object.prototype

4.p.___proto__.__proto__.__proto__== object.prototype.__proto__ == null          

5.通過__proto__形成原型鏈而非protrotype

原文: 

深入JavaScript之原型和原型鏈

所有引用型別 函式 陣列 物件 都擁有 proto 屬性 隱式原型 所有函式擁有prototype屬性 顯式原型 僅限函式 原型物件 擁有prototype屬性的物件,在定義函式時就被建立 建立建構函式 function word words word.prototype 建立例項 var w ne...

JavaScript系列 深入之從原型到原型鏈

本文詳情 建構函式建立物件 先使用建構函式建立乙個物件 function person var person new person person.name mit console.log person.name 在這個例子中,person 就是乙個建構函式,我們使用 new 建立了乙個例項物件 pe...

javascript之原型,原型鏈

1.定義 原型是function物件的乙個屬性,它定義了建構函式製造出的物件的公共祖先。通過該建構函式產生的物件,可以繼承該原型的屬性和方法。原型也是物件。2.利用原型特點和概念,可以提取共有屬性。3.物件如何檢視原型 隱式屬性 proto 4.物件如何檢視物件的建構函式 constructor v...