js原型,原型鏈

原型相關(guān)的屬性也比較多,對(duì)象有”prototype”屬性,函數(shù)對(duì)象有”prototype”屬性,原型對(duì)象有”constructor”屬性。

在JavaScript中,原型也是一個(gè)對(duì)象,通過原型可以實(shí)現(xiàn)對(duì)象的屬性繼承,JavaScript的對(duì)象中都包含了一個(gè)”[[Prototype]]”內(nèi)部屬性,這個(gè)屬性所對(duì)應(yīng)的就是該對(duì)象的原型。

在JavaScript中,每個(gè)函數(shù) 都有一個(gè)prototype屬性,當(dāng)一個(gè)函數(shù)被用作構(gòu)造函數(shù)來創(chuàng)建實(shí)例時(shí),這個(gè)函數(shù)的prototype屬性值會(huì)被作為原型賦值給所有對(duì)象實(shí)例(也就是設(shè)置 實(shí)例的`__proto__`屬性),也就是說,所有實(shí)例的原型引用的是函數(shù)的prototype屬性。(****`只有函數(shù)對(duì)象才會(huì)有這個(gè)屬性!`****)

new 的過程分為三步

var p = new Person('張三',20);

1. var p={}; 初始化一個(gè)對(duì)象p。

2. p._proto_=Person.prototype;,將對(duì)象p的 __proto__ 屬性設(shè)置為 Person.prototype

3. Person.call(p,”張三”,20);調(diào)用構(gòu)造函數(shù)Person來初始化p。關(guān)于call/apply使用

原型鏈

因?yàn)槊總€(gè)對(duì)象和原型都有原型,對(duì)象的原型指向原型對(duì)象,

而父的原型又指向父的父,這種原型層層連接起來的就構(gòu)成了原型鏈。

一、屬性查找

當(dāng)查找一個(gè)對(duì)象的屬性時(shí),JavaScript 會(huì)向上遍歷原型鏈,直到找到給定名稱的屬性為止,到查找到達(dá)原型鏈的頂部(也就是 Object.prototype),如果仍然沒有找到指定的屬性,就會(huì)返回 undefined。

function Person(name, age){

this.name = name;

this.age = age;

}

Person.prototype.MaxNumber = 9999;

Person.__proto__.MinNumber = -9999;

var will = new Person("Will", 28);

console.log(will.MaxNumber); // 9999

console.log(will.MinNumber); // undefined

在這個(gè)例子中分別給”Person.prototype “和” Person.proto”這兩個(gè)原型對(duì)象添加了”MaxNumber “和”MinNumber”屬性,這里就需要弄清”prototype”和”proto”的區(qū)別了。

“Person.prototype “對(duì)應(yīng)的就是Person構(gòu)造出來所有實(shí)例的原型,也就是說”Person.prototype “屬于這些實(shí)例原型鏈的一部分,所以當(dāng)這些實(shí)例進(jìn)行屬性查找時(shí)候,就會(huì)引用到”Person.prototype “中的屬性。


當(dāng)使用這種方式創(chuàng)建一個(gè)對(duì)象的時(shí)候,原型鏈就變成下圖了. July對(duì)象的原型是”O(jiān)bject.prototype”也就是說對(duì)象的構(gòu)建方式會(huì)影響原型鏈的形式。

{}對(duì)象原型鏈結(jié)構(gòu)圖

綜圖所述

1. 所有的對(duì)象都有__proto__屬性,該屬性對(duì)應(yīng)該對(duì)象的原型.

2. 所有的函數(shù)對(duì)象都有prototype屬性,該屬性的值會(huì)被賦值給該函數(shù)創(chuàng)建的對(duì)3. 象的_proto_屬性.

4. 所有的原型對(duì)象都有constructor屬性,該屬性對(duì)應(yīng)創(chuàng)建所有指向該原型的實(shí)例的構(gòu)造函數(shù).

5. 函數(shù)對(duì)象和原型對(duì)象通過prototype和constructor屬性進(jìn)行相互關(guān)聯(lián).



另一種解釋:

對(duì)于新人來說,JavaScript的原型是一個(gè)很讓人頭疼的事情,一來prototype容易與__proto__混淆,二來它們之間的各種指向?qū)嵲谟行?fù)雜,其實(shí)市面上已經(jīng)有非常多的文章在嘗試說清楚,有一張所謂很經(jīng)典的圖,上面畫了各種線條,一會(huì)連接這個(gè)一會(huì)連接那個(gè),說實(shí)話我自己看得就非常頭暈,更談不上完全理解了。所以我自己也想嘗試一下,看看能不能把原型中的重要知識(shí)點(diǎn)拆分出來,用最簡(jiǎn)單的圖表形式說清楚。

我們知道原型是一個(gè)對(duì)象,其他對(duì)象可以通過它實(shí)現(xiàn)屬性繼承。但是尼瑪除了prototype,又有一個(gè)__proto__是用來干嘛的?長(zhǎng)那么像,讓人怎么區(qū)分呢?它們都指向誰(shuí),那么混亂怎么記啊?原型鏈又是什么鬼?相信不少初學(xué)者甚至有一定經(jīng)驗(yàn)的老鳥都不一定能完全說清楚,下面用三張簡(jiǎn)單的圖,配合一些示例代碼來理解一下。

一、prototype和__proto__的區(qū)別

vara ={};

console.log(a.prototype);//undefinedconsole.log(a.__proto__);//Object {}varb =function(){}

console.log(b.prototype);//b {}console.log(b.__proto__);//function() {}

/*1、字面量方式*/vara ={};

console.log(a.__proto__);//Object {}console.log(a.__proto__=== a.constructor.prototype);//true/*2、構(gòu)造器方式*/varA =function(){};vara =newA();

console.log(a.__proto__);//A {}console.log(a.__proto__=== a.constructor.prototype);//true/*3、Object.create()方式*/vara1 = {a:1}vara2 =Object.create(a1);

console.log(a2.__proto__);//Object {a: 1}console.log(a.__proto__=== a.constructor.prototype);//false(此處即為圖1中的例外情況)

varA =function(){};vara =newA();

console.log(a.__proto__);//A {}(即構(gòu)造器function A 的原型對(duì)象)console.log(a.__proto__.__proto__);//Object {}(即構(gòu)造器function Object 的原型對(duì)象)console.log(a.__proto__.__proto__.__proto__);//null

參考:http://www.cnblogs.com/shuiyi/p/5305435.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容