所有引用型別(函式,陣列,物件)都擁有__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...