JavaScript中的幾個關鍵概念的理解-原型鏈的構建
更新時間:2011年05月12日 00:21:45 投稿:mdxy-dxy
JavaScript中的prototype,標準翻譯為“原型”,表示對象的初始形態(tài)
Javascript中所有function中都有一個prototype屬性,并且這個prototype屬性是一個object類型的對象,所有由該function構造出來的對象都具有這個prototype上的特性,也就是說可以用構造出來的對象直接訪問prototype上的屬性和方法。
下面一段代碼演示prototype的使用方法:
復制代碼 代碼如下:
function Staff(name) {
this.name = name;
}
Staff.prototype.say = function() {
alert(this.name + " say hello");
}
var staff1 = new Staff("hunter");
var staff2 = new Staff("dangjian");
staff1.say();
staff2.say();
運行如上的程序,可知prototype上的屬性和方法可以通過創(chuàng)建的對象之間調(diào)用,更重要的是prototype中的屬性和方法是在同類型的對象中是共享的
復制代碼 代碼如下:
alert( staff1.say == staff2.say);
prototype另外一個常用的特性是通過prototype構建對象的繼承關系,通過把基類對象賦給子類的prototype的方式可以模擬面向?qū)ο笾械睦^承關系,這就是大家經(jīng)常說的JavaScript的面向?qū)ο髾C制。如下的代碼段演示了利用這一特性構建對象的繼承關系:
復制代碼 代碼如下:
function Staff(name) { // 基類
this.name = name;
}
Staff.prototype.say = function() {
alert(this.name + " say hello");
}
function ManStaff(name, age) { // 子類
this.name = name;
this.age = age;
}
ManStaff.prototype = new Staff(); // 建立繼承關系
var manStaff1 = new ManStaff("hunter", 22);
var manStaff2 = new ManStaff("dangjian", 32);
manStaff1.say();
manStaff2.say();
運行代碼可知,ManStaff對象中具有了基類Staff中的Say方法,這種繼承方式在JavaScript中是通過prototype鏈來實現(xiàn)的。大家可能熟悉以上的prototype用法,可是作為程序員,我們不光要知道其用法,我們更應該理解其可是prototype的內(nèi)部機制。下面我們來分析prototype的原理以及prototype鏈的實現(xiàn)。
要理解prototype的機制就必須要了解JavaScript中function的創(chuàng)建方式。
當代碼執(zhí)行到function Staff(name) {this.name = name;}時,相當于執(zhí)行var Staff = new Function(“name”, "this.name = name”)解釋器將使用預定義好的Function() constructor,來創(chuàng)建一個function類型的object出來,即Staff。
隨后給創(chuàng)建好的Staff對象添加__proto__屬性,并賦值為Function的構造器的prototype,這一步是所有對象創(chuàng)建過程中都有的步驟,在執(zhí)行類似var x = new X()方式是,都會把X的prototype賦值給x的__proto__,類似如下的賦值:
復制代碼 代碼如下:
Staff.__proto__ = Function.prototype;
接下來給Staff創(chuàng)建prototype屬性,這一步是創(chuàng)建function類型的對象具有的步驟,創(chuàng)建的過程如下偽代碼:
復制代碼 代碼如下:
var o = new Object();
o.constructor = Base;
Staff.prototype = o;
如上的分析我們可知,當創(chuàng)建對象時,會創(chuàng)建一個私有屬性__proto__,當創(chuàng)建function是會創(chuàng)建一個prototype屬性。因為Staff是一個function類型的對象,所以會同時具有這兩個屬性。
這兩個屬性是構建原型鏈的關鍵屬性。我們來分析執(zhí)行代碼 var staff1 = new Staff(“hunter”)時,原型是如何傳遞的。
根據(jù)如上分析,staff1.__proto__ = Staff.prototype,而Staff.prototype又是一個由Object創(chuàng)建的對象,即Staff.prototype.__proto__ = Object.prototype,所以staff1.__proto__ .__proto__ 指向的是Object.prototype,即staff1.__proto__ .__proto__ == Object.prototype,這就是原型鏈,當要讀取某個對象的屬性時,JS首先找對象本身是否有這個屬性,如果沒有就會順著原型鏈一直尋找這個屬性。
知道了原型鏈的原理,那么就很容易根據(jù)這個原理來構建Javascript中的對象繼承。
由如上的分析,我們可知原型鏈的頂端都是Object.prototype,這就意味著在構建的繼承關系中Object是所有對象的基類,可以運行如下的代碼驗證。
復制代碼 代碼如下:
Object.prototype.location = "China";
function Staff(name) { // 基類
this.name = name;
}
Staff.prototype.say = function() {
alert(this.name + " say hello");
}
var ManStaff1 = new Staff("hunter");
var ManStaff2 = new Staff("dangjian");
alert(ManStaff1.location);
alert(ManStaff2.location);
運行結果知道,Object是Staff的基類,那么要如何構建一個Staff的子類呢?
理解了上面函數(shù)的建立原理,我們很容易寫出如下的代碼:
復制代碼 代碼如下:
function Staff(name) { // 基類
this.name = name;
}
Staff.prototype.say = function() {
alert(this.name + " say hello");
}
function ManStaff(name, age) { // 子類
Staff.call(this,name);
this.age = age;
}
ManStaff.prototype = new Staff(); // 建立繼承關系
var ManStaff1 = new ManStaff("hunter", 22);
var ManStaff2 = new ManStaff("dangjian", 32);
ManStaff1.say();
ManStaff2.say();
建立繼承關系的就是這句:ManStaff.prototype = new Staff(); ,繼承關系推算如下:ManStaff1.__proto__ = =ManStaff.prototype, ManStaff.prototype.__proto__ = Staff.prototype, Staff.prototype.__proto__ == Object.prototype;則ManStaff1.__proto__.__proto__.__proto__ == Object.prototype。
javascript中的這種繼承關系比較傳統(tǒng)面向?qū)ο蟮睦^承關系更松散,構建方式也比較難以理解,但是作為腳本語言,其功能已經(jīng)是非常強大了。
您可能感興趣的文章:
- 無廢話JavaScript教程(全集)
- 國外的為初學者寫的JavaScript教程
- js原型鏈原理看圖說明
- 基于JavaScript實現(xiàn)繼承機制之原型鏈(prototype chaining)的詳解
- 基于JavaScript實現(xiàn)繼承機制之構造函數(shù)+原型鏈混合方式的使用詳解
- JS繼承--原型鏈繼承和類式繼承
- 深入理解JavaScript系列(6) 強大的原型和原型鏈
- javascript學習筆記(九)javascript中的原型(prototype)及原型鏈的繼承方式
- JavaScript 原型鏈學習總結
- Javascript之旅 對象的原型鏈之由來
- Javascript學習筆記7 原型鏈的原理
- javascript prototype 原型鏈
- javascript教程之不完整的繼承(js原型鏈)
相關文章
Bootstrap modal 多彈窗之疊加顯示不出彈窗問題的解決方案
Bootstrap modal 多彈窗之疊加顯示不出彈窗問題,今天小編抽時間給大家分享下解決方案,需要的朋友參考下2017-02-02JavaScript數(shù)據(jù)庫TaffyDB用法實例分析
這篇文章主要介紹了JavaScript數(shù)據(jù)庫TaffyDB用法,實例分析了TaffyDB數(shù)據(jù)庫的定義、查詢、更新、刪除等操作的相關使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07javascript function(函數(shù)類型)使用與注意事項小結
這篇文章主要介紹了javascript function(函數(shù)類型)使用與注意事項,結合實例形式較為詳細的分析了Function(函數(shù))類型的基本聲明、屬性、方法相關操作技巧與使用注意事項,需要的朋友可以參考下2019-06-06快速解決js中window.location.href不工作的問題
下面小編就為大家?guī)硪黄焖俳鉀Qjs中window.location.href不工作的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11