原型和原型鏈
原型:JavaScript中,一共有兩種類型的值,原始值和對象值.每個對象都有一個內部屬性[[prototype]],我們通常稱之爲原型.原型是一個對象,其他對象可以通過它實現屬性繼承。
原型鏈:原型的值可以是一個對象,也可以是null.如果它的值是一個對象,則這個對象也一定有自己的原型.這樣就形成了一條線性的鏈,我們稱之爲原型鏈
Prototype和_proto_的區別:
Prototype是函數才擁有的屬性。
_proto_是每個對象都有的屬性,但_proto_不是一個規範的屬性,只有部分瀏覽器實現了此屬性。
大多數情況下,_proto_可以理解爲“構造器的原型”.
_proto_===constructorl.prototype(通過Object.create()創建的對象,不適用此等式。)
由於_proto_是任何對象都有的屬性,而js裏萬物皆爲對象。所以會形成一條_proto_鏈接起來的鏈條,遞歸訪問_proto_必須最終到頭,並且值是null。
當js引擎查找對象的屬性時,先查找對象本身是否存在該屬性,如果不存在,會在原型鏈上查找,但不會查找自身的prototype。
例子:
var A=function(){}
var a=new A();
console.log(a._proto_)//A {} 構造器function A的原型對象。
console.log(a._proto_._proto_); Object{}
console.log(a._proto_._proto_);//null
圖示解析:
_proto_的指向取決於對象創建時的實現方式。
1、 字面量方式
var a={};
var a={};
a._proto_ //object {}
a._proto_ === a.constructor.prototype(true)
2、 構造器方式
var A=function(){}
var a=new A();
var A=function(){};
var a=new A();
a._proto_ //A {}
a._proto_ === a.constructor.prototype(true)
3、 Object.create方法
var a1={};
var a2=Object.create(a1)
var a1={a:1;};
var a2=Object.create(a1);
a2._proto_//Object {a:1}
a2._proto_===a2.constructor.prototype(false)