javascript中的原型鏈深入理解
更新時(shí)間:2014年02月24日 15:23:51 作者:
要弄清楚原型鏈就要先弄清楚 function 類型,在javascript中沒有類的概念,都是函數(shù),所以它是一門函數(shù)式的編程語言
要弄清楚原型鏈就要先弄清楚 function 類型,在javascript中沒有類的概念,都是函數(shù),所以它是一門函數(shù)式的編程語言。類有一個(gè)很重要的特性,就是它可以根據(jù)它的構(gòu)造函數(shù)來創(chuàng)建以它為模板的對象。在javascript中,函數(shù)就有2個(gè)功能
第一、 作為一般函數(shù)調(diào)用
第二、 作為它原型對象的構(gòu)造函數(shù) 也就new()
我們來看一個(gè)例子
function a(){
this.name = 'a';
}
當(dāng)創(chuàng)建一個(gè)函數(shù),它會發(fā)生什么呢?
第一、它會創(chuàng)建1個(gè)函數(shù)對象 也就是a 本身
第二、它會創(chuàng)建1個(gè)原型對象@a(用@來表示)
第三、函數(shù)對象會有一個(gè)prototype指針,它指向了對應(yīng)的原型對象,這里就指向了@a
第四、@a對象中有一個(gè)construtor指針,指向它的構(gòu)造函數(shù),這里就指向了a
http://img.blog.csdn.net/20140222125611500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGpsMTU3MDEx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
這個(gè)prototype屬性究竟有什么用呢?
其實(shí)prototype 屬性表示當(dāng)前函數(shù)能夠控制的范圍(或者說它指明了當(dāng)前函數(shù)是誰的構(gòu)造函數(shù)),這里a就是@a原型對象的構(gòu)造函數(shù),所以我們會看見有這種寫法
function a(){
this.name = 'a';
}
var a1 = new a();
這就和其他常見語言相似了,new 就是調(diào)用原型對象(通過prototype指針)里面構(gòu)造函數(shù)(constructor)創(chuàng)建一個(gè)新的對象實(shí)例。
那么修改了prototype指向?qū)ο罄锩娴膶傩?,也就影響了所有以它為模板?chuàng)建的實(shí)例,我們可以這樣來驗(yàn)證
function a(){
this.name = 'a';
}
var a1 = new a();
a.prototype.age = 1;
alert(a1.age);
結(jié)果:1
那為什么a1對象可以直接訪問到age屬性呢?a1對象里面我并沒有定義age屬性啊,
那是因?yàn)樗袑?shí)例里面都會有一個(gè)引用_proto_(在firfox,chrome下可以直接訪問,ie不支持)指向了這個(gè)原型,這里就是指向了@a,
function a(){
this.name = 'a';
}
var a1 = new a();
alert(a1._proto_ == a.prototype)
結(jié)果:true
在訪問屬性的時(shí)候,會先在a1對象內(nèi)部中尋找,如果沒有,就會順著_proto_指向的對象里面去尋找,這里會到@a中尋找,找到就返回值,沒有找到就返回undefined,用個(gè)成語來形容,就是順藤摸瓜嘛!
至此原型鏈的含義就出來了,由于原型對象也有一個(gè)_proto_指針,又指向了另一個(gè)原型,一個(gè)接一個(gè),就形成了原型鏈。Object.prototype是最頂層的原型,所以如果修改了Object.prototype的屬性,那么就影響了所有的對象。
在來看一段代碼
function a(){
this.name = 'a';
}
function b(){
this.age = 1;
}
b.prototype = new a();
alert(new b().name);
我們顯示的將b的原型指向了a的一個(gè)實(shí)例,然后,b的實(shí)例也可以訪問a的屬性了。這就是javascript的繼承了,那為什么b.prototype 指向的是a的一個(gè)實(shí)例,而不是直接指向a.prototype 呢?
b.prototype = new a.prototype;
如果像上面這么寫,修改p.prototype中的屬性,那么a的原型也會改變了,相當(dāng)于是子類修改了父類,并且子類和父類的屬性糅合在了一起,這顯然是不合適的。換句話說,b也成為了@a的構(gòu)造函數(shù),a,b成了平級的關(guān)系。
我們可以下一個(gè)定義:
函數(shù)a 繼承函數(shù)b 也就是讓函數(shù)a成為函數(shù)b原型的一個(gè)實(shí)例的構(gòu)造函數(shù),構(gòu)造函數(shù)里面聲明的屬性是函數(shù)a自己的,原型實(shí)例里面的屬性就是繼承b的
var $ = jQuery = function(selector,context){
//不可能在自己的構(gòu)造函數(shù)中又一次構(gòu)造自己,所以返回了另外一個(gè)構(gòu)造函數(shù)的實(shí)例
return new init(selector,context);
}
jQuery.fn = jQuery.prototype = {
size:function(){
return this.length;
}
}
function init (selector,context){
}
init.prototype = jQuery.fn;;
}
這是jquery的一段源碼,我們在使用jquery的時(shí)候,并沒有使用new關(guān)鍵字,那它是如何構(gòu)造對象的呢?
用上面的知識,可以解釋,jquery這里只是一個(gè)一般函數(shù)的調(diào)用,它返回了jquery原型的另外一個(gè)構(gòu)造函數(shù)創(chuàng)建的對象,也就是new init()
第一、 作為一般函數(shù)調(diào)用
第二、 作為它原型對象的構(gòu)造函數(shù) 也就new()
我們來看一個(gè)例子
復(fù)制代碼 代碼如下:
function a(){
this.name = 'a';
}
當(dāng)創(chuàng)建一個(gè)函數(shù),它會發(fā)生什么呢?
第一、它會創(chuàng)建1個(gè)函數(shù)對象 也就是a 本身
第二、它會創(chuàng)建1個(gè)原型對象@a(用@來表示)
第三、函數(shù)對象會有一個(gè)prototype指針,它指向了對應(yīng)的原型對象,這里就指向了@a
第四、@a對象中有一個(gè)construtor指針,指向它的構(gòu)造函數(shù),這里就指向了a
http://img.blog.csdn.net/20140222125611500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGpsMTU3MDEx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
這個(gè)prototype屬性究竟有什么用呢?
其實(shí)prototype 屬性表示當(dāng)前函數(shù)能夠控制的范圍(或者說它指明了當(dāng)前函數(shù)是誰的構(gòu)造函數(shù)),這里a就是@a原型對象的構(gòu)造函數(shù),所以我們會看見有這種寫法
復(fù)制代碼 代碼如下:
function a(){
this.name = 'a';
}
var a1 = new a();
這就和其他常見語言相似了,new 就是調(diào)用原型對象(通過prototype指針)里面構(gòu)造函數(shù)(constructor)創(chuàng)建一個(gè)新的對象實(shí)例。
那么修改了prototype指向?qū)ο罄锩娴膶傩?,也就影響了所有以它為模板?chuàng)建的實(shí)例,我們可以這樣來驗(yàn)證
復(fù)制代碼 代碼如下:
function a(){
this.name = 'a';
}
var a1 = new a();
a.prototype.age = 1;
alert(a1.age);
結(jié)果:1
那為什么a1對象可以直接訪問到age屬性呢?a1對象里面我并沒有定義age屬性啊,
那是因?yàn)樗袑?shí)例里面都會有一個(gè)引用_proto_(在firfox,chrome下可以直接訪問,ie不支持)指向了這個(gè)原型,這里就是指向了@a,
復(fù)制代碼 代碼如下:
function a(){
this.name = 'a';
}
var a1 = new a();
alert(a1._proto_ == a.prototype)
結(jié)果:true
在訪問屬性的時(shí)候,會先在a1對象內(nèi)部中尋找,如果沒有,就會順著_proto_指向的對象里面去尋找,這里會到@a中尋找,找到就返回值,沒有找到就返回undefined,用個(gè)成語來形容,就是順藤摸瓜嘛!
至此原型鏈的含義就出來了,由于原型對象也有一個(gè)_proto_指針,又指向了另一個(gè)原型,一個(gè)接一個(gè),就形成了原型鏈。Object.prototype是最頂層的原型,所以如果修改了Object.prototype的屬性,那么就影響了所有的對象。
在來看一段代碼
復(fù)制代碼 代碼如下:
function a(){
this.name = 'a';
}
function b(){
this.age = 1;
}
b.prototype = new a();
alert(new b().name);
我們顯示的將b的原型指向了a的一個(gè)實(shí)例,然后,b的實(shí)例也可以訪問a的屬性了。這就是javascript的繼承了,那為什么b.prototype 指向的是a的一個(gè)實(shí)例,而不是直接指向a.prototype 呢?
復(fù)制代碼 代碼如下:
b.prototype = new a.prototype;
如果像上面這么寫,修改p.prototype中的屬性,那么a的原型也會改變了,相當(dāng)于是子類修改了父類,并且子類和父類的屬性糅合在了一起,這顯然是不合適的。換句話說,b也成為了@a的構(gòu)造函數(shù),a,b成了平級的關(guān)系。
我們可以下一個(gè)定義:
函數(shù)a 繼承函數(shù)b 也就是讓函數(shù)a成為函數(shù)b原型的一個(gè)實(shí)例的構(gòu)造函數(shù),構(gòu)造函數(shù)里面聲明的屬性是函數(shù)a自己的,原型實(shí)例里面的屬性就是繼承b的
復(fù)制代碼 代碼如下:
var $ = jQuery = function(selector,context){
//不可能在自己的構(gòu)造函數(shù)中又一次構(gòu)造自己,所以返回了另外一個(gè)構(gòu)造函數(shù)的實(shí)例
return new init(selector,context);
}
jQuery.fn = jQuery.prototype = {
size:function(){
return this.length;
}
}
function init (selector,context){
}
init.prototype = jQuery.fn;;
}
這是jquery的一段源碼,我們在使用jquery的時(shí)候,并沒有使用new關(guān)鍵字,那它是如何構(gòu)造對象的呢?
用上面的知識,可以解釋,jquery這里只是一個(gè)一般函數(shù)的調(diào)用,它返回了jquery原型的另外一個(gè)構(gòu)造函數(shù)創(chuàng)建的對象,也就是new init()
相關(guān)文章
javascript使用window.open提示“已經(jīng)計(jì)劃系統(tǒng)關(guān)機(jī)”的原因
這篇文章主要介紹了javascript使用window.open提示“已經(jīng)計(jì)劃系統(tǒng)關(guān)機(jī)”的原因,本文得出結(jié)論是安裝了系統(tǒng)更新或其它原因,要把系統(tǒng)重啟時(shí)才會提示這個(gè)問題,所以,遇到這個(gè)問題,重啟你的電腦吧2014-08-08JavaScript的document對象和window對象詳解
JavaScript的document對象和window對象詳解,js經(jīng)常用得到的知識,了解下。2010-12-12document.getElementById獲取控件對象為空的解決方法
今天寫個(gè)網(wǎng)頁,想在頁面加載onLoad時(shí),動(dòng)態(tài)顯示由后臺其他程序傳來的數(shù)據(jù)時(shí),用document.getElementById獲取控件對象總是為空。但是檢查了這個(gè)id確實(shí)是存在的??聪挛牡氖纠徒鉀Q方法2013-11-11詳解JavaScript正則表達(dá)式中的global屬性的使用
這篇文章主要介紹了詳解JavaScript正則表達(dá)式中的global屬性的使用,是JS學(xué)習(xí)進(jìn)階中的重要知識點(diǎn),需要的朋友可以參考下2015-06-06