亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript中的原型和繼承詳解(圖文)

2019-11-20 14:20:34
字體:
來源:轉載
供稿:網友

  請在此暫時忘記之前學到的面向對象的一切知識。這里只需要考慮賽車的情況。是的,就是賽車。

  最近我正在觀看 24 Hours of Le Mans ,這是法國流行的一項賽事。最快的車被稱為 Le Mans 原型車。這些車雖然是由“奧迪”或“標致”這些廠商制造的,可它們并不是你在街上或速公路上所見到的那類汽車。它們是專為參加高速耐力賽事而制造出來的。

  廠家投入巨額資金,用于研發、設計、制造這些原型車,而工程師們總是努力嘗試將這項工程做到極致。他們在合金、生物燃料、制動技術、輪胎的化合物成分和安全特性上進行了各種實驗。隨著時間的推移,這些實驗中的某些技術經過反復改進,隨之進入到車輛的主流產品線中。你所駕駛車輛的某些技術,有可能是在賽車原型上第一次亮相的。

  你也可以說,這些主流車輛繼承了來自賽車的技術原型。

  到現在,我們就有討論 JavaScript 中的原型和繼承問題的基礎了。它雖然并不像你在 C++、Java 或 C# 中了解的經典繼承模式一樣,但這種方式同樣強大,并且有可能會更加靈活。

 有關對象和類

  JavaScript 中全是對象,這指的是傳統意義上的對象,也就是“一個包含了狀態和行為的單一實體”。例如,JavaScript 中的數組是含有數個值,并且包含 push、reverse 和 pop 方法的對象。

var myArray = [1, 2];myArray.push(3);myArray.reverse();myArray.pop();var length = myArray.length;

  現在問題是,push 這樣的方法是從何而來的呢?我們前面提到的那些靜態語言使用“類語法”來定義對象的結構,但是 JavaScript 是一個沒有“類語法”的語言,無法用 Array“類”的語法來定義每個數組對象。而因為 JavaScript 是動態語言,我們可以在實際需要的情況下,將方法任意放置到對象上。例如下面的代碼,就在二維空間中,定義了用來表示一個點的點對象,同時還定義了一個 add 方法。

var point = {  x : 10,  y : 5,  add: function(otherPoint) {    this.x += otherPoint.x;    this.y += otherPoint.y;  }};

  但是上面的做法可擴展性并不好。我們需要確保每一個點對象都含有一個 add 方法,同時也希望所有點對象都共享同一個 add 方法的實現,而不是這個方法手工添加每一個點對象上。這就是原型發揮它作用的地方。

 有關原型

  在 JavaScript 中,每個對象都保持著一塊隱藏的狀態 ―― 一個對另一個對象的引用,也被稱作原型。我們之前創建的數組引用了一個原型對象,我們自行創建的點對象也是如此。上面說原型引用是隱藏的,但也有 ECMAScript(JavaScript 的正式名稱)的實現可以通過一個對象的__proto__屬性(例如谷歌瀏覽器)訪問到這個原型引用。從概念上講,我們可以將對象當作類似于 圖1 所表示的對象 ―― 原型的關系。

 

1

  展望未來,開發者將能夠使用 Object.getPrototypeOf 函數,代替__proto__屬性,取得對象原型的引用。在本文寫出的時候,已經可以在 Google Chrome,FIrefox 和 IE9 瀏覽器中使用 Object.getPrototypeOf 函數。更多瀏覽器在未來會實現此功能,因為它已經是 ECMAScript 標準的一部分了。我們可以使用下面的代碼,來證明我們建立的 myArray 和點對象引用的是兩個不同的原型對象。

  1. Object.getPrototypeOf(point) != Object.getPrototypeOf(myArray);

  對于本文的其余部分,我將交叉使用 __proto__和Object.getPrototypeOf 函數,主要是因為 __proto__ 在圖和句子中更容易識別。需要記住的是它(__proto__)不是標準,而 Object.getPrototypeOf 函數才是查看對象原型的推薦方法。

  是什么讓原型如此特別?

  我們還沒有回答這個問題:數組中 push 這樣的方法是從何而來的呢?答案是:它來源于 myArray 原型對象。圖 2 是 Chrome 瀏覽器中腳本調試器的屏幕截圖。我們已經調用 Object.getPrototypeOf 方法查看 myArray 的原型對象。

 

2

  注意 myArray 的原型對象中有許多方法,包括那些在代碼示例中調用的 push、pop 和 reverse 方法。因此,原型對象中的確包括 push 方法,但是 myArray 方法如何引用到呢?

myArray.push(3);

  了解其工作原理的第一步,是要認識到原型并不是特別的。原型只是普通的對象??梢越o原型添加方法,屬性,并把他們當作其他 JavaScript 對象一樣看待。然而,套用喬治?奧威爾的小說《動物農場》中“豬”的說法 ―― 所有的對象應當是平等的,但有些對象(遵守規則的)比其他人更加平等。

  JavaScript 中的原型對象的確是特殊的,因為他們遵從以下規則。當我們告訴 JavaScript 我們要調用一個對象的 push 方法,或讀取對象的 x 屬性時,運行時會首先查找對象本身。如果運行時找不到想要的東西,它就會循著 __proto__ 引用和對象原型尋找該成員。當我們  調用 myArray 的 push 方法時,JavaScript 并沒有在 myArray 對象上發現 push 方法,而是在 myArray 的原型對象上找到了,于是 JavaScript 調用此方法(見圖 3)。

3

  上面所描述的行為是指一個對象本身繼承了原型上的任何方法或屬性。JavaScript 中其實不需要使用類語法也能實現繼承。就像從賽車原型上繼承了相應的技術的車,一個 JavaScript 對象也可以從原型對象上繼承功能特性。

  圖 3 還展示了每個數組對象同時也可以維護自身的狀態和成員。在請求得到 myArray 的 length 屬性的情況下,JavaScript 會取得 myArray 中 length 屬性的值,而不會去讀取原型中的對應值。我們可以通過向對象上添加 push 這樣的方法來“重寫”push 方法。這樣就會有效地隱藏原型中的 push 方法實現。

 共享原型

  JavaScript 中原型的真正神奇之處是多個對象如何維持對同一個原型對象的引用。例如,如果我們創建了這樣的兩個數組:

var myArray = [1, 2];var yourArray = [4, 5, 6];

  那么這兩個數組將共享同一個原型對象,而下面的代碼計算結果為 true:

Object.getPrototypeOf(myArray) === Object.getPrototypeOf(yourArray);

  如果我們引用兩個數組對象上的 push 方法,JavaScript 會去尋找原型上共享的 push 方法。

4

  JavaScript 中的原型對象提供繼承功能,同時也就實現了該方法實現的共享。原型也是鏈式的。換句話說,因為原型對象只是一個對象,所以一個原型對象可以維持到另一個原型對象的引用。如果你重新審視圖 2 便可以看到,原型的 __proto__ 屬性是一個指向另一個原型的非空值。當 JavaScript 查找像 push 方法這樣的成員時,它會循著原型引用鏈檢查每一個對象,直到找到該成員,或者抵達原型鏈的末端。原型鏈為繼承和共享開辟了一條靈活的途徑。

  你可能會問的下一個問題是:我該如何設置那些自定義對象的原型引用呢?例如前面所使用的點對象,如何才能將 add 方法添加到原型對象中,并從多個點對象中繼承方法呢?在回答這個問題之前,我們需要看看函數。

 有關函數

  JavaScript 中的函數也是對象。這樣的表述帶來了幾個重要的結果,而我們并不會在本文中涉及所有的事項。這其中,能將一個函數賦值給一個變量,并且將一個函數作為參數傳遞給另一個函數的能力構成了現代 JavaScript 編程表達的基本范式。

  我們需要關注的是,函數本身就是對象,因此函數可以有自身的方法,屬性,并且引用一個原型對象。讓我們來討論下面的代碼的含義。

// 這將返回 true:typeof (Array) === "function"http:// 這樣的表達式也是:Object.getPrototypeOf(Array) === Object.getPrototypeOf(function () { })// 這樣的表達式同樣:Array.prototype != null

  代碼中的第一行證明, JavaScript 中的數組是函數。稍后我們將看到如何調用 Array 函數創建一個新的數組對象。下一行代碼,證明了 Array 對象使用與任何其他函數對象相同的原型,就像我們看到數組對象間共享相同的原型一樣。最后一行代碼證明了 Array 函數都有一個 prototype 屬性,而這個 prototype 屬性指向一個有效的對象。這個 prototype 屬性十分重要。

  JavaScript 中的每一個函數對象都有 prototype 屬性。千萬不要混淆這個 prototype 屬性的 __proto__ 屬性。他們用途并不相同,也不是指向同一個對象。

// 返回 trueObject.getPrototypeOf(Array) != Array.prototype

  Array.__proto__ 提供的是 數組原型 亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

成人免费xxxxx在线观看| 欧美日韩午夜激情| 亚洲第一免费网站| 国产一区二区久久精品| 最好看的2019年中文视频| 亚洲人成在线观看网站高清| 欧美另类xxx| 国产精品久久久久久久一区探花| 成人妇女免费播放久久久| 久久精品电影一区二区| 国产精品久久久一区| 亚洲精品v天堂中文字幕| 色婷婷av一区二区三区在线观看| 不卡av日日日| 久久久精品一区二区三区| 国产丝袜一区视频在线观看| 97超级碰碰人国产在线观看| 欧美肥老太性生活视频| 久久福利网址导航| 国产在线视频2019最新视频| 亚洲欧美色婷婷| 国产成人jvid在线播放| 97超级碰碰碰| 久久精品视频一| 欧美成人在线免费| 国产经典一区二区| 亚洲高清不卡av| 久久亚洲成人精品| 欧美国产日韩免费| 91精品在线影院| 九九视频直播综合网| 最新国产精品亚洲| 亚洲精品视频二区| 成人国内精品久久久久一区| 国产一区二区视频在线观看| 欧美黑人狂野猛交老妇| 久久免费成人精品视频| 欧美精品成人在线| 国产精品综合久久久| 91色p视频在线| 欧美床上激情在线观看| 久久久久中文字幕2018| 久久99久久久久久久噜噜| 欧美激情高清视频| 久久久人成影片一区二区三区| 亚洲加勒比久久88色综合| 国产在线98福利播放视频| 欧美三级欧美成人高清www| 77777少妇光屁股久久一区| 久久99久国产精品黄毛片入口| 日本精品视频网站| 久久久精品免费视频| 97涩涩爰在线观看亚洲| 一区二区三区高清国产| 精品久久久999| 奇米成人av国产一区二区三区| 欧美日韩福利视频| 色妞色视频一区二区三区四区| 国产在线观看一区二区三区| 国产精品美女999| 国产日韩欧美影视| 精品国产精品三级精品av网址| 亚洲乱码国产乱码精品精| 亚洲欧美综合精品久久成人| 国外成人在线直播| 国产视频一区在线| 亚洲人成电影网站色…| 国产脚交av在线一区二区| 日韩激情视频在线| 国产精品久久久久久超碰| 欧美中文字幕在线视频| 国产午夜精品一区理论片飘花| 久久久精品日本| 久久九九热免费视频| 久久久久久高潮国产精品视| 久久成人一区二区| 亚洲自拍偷拍网址| 中文字幕亚洲一区二区三区五十路| 久久久91精品国产一区不卡| 高清在线视频日韩欧美| 一个色综合导航| 久久久在线视频| 精品久久久久人成| 亚洲第一视频在线观看| 最近中文字幕mv在线一区二区三区四区| 日韩高清电影免费观看完整| 欧美一区二区三区艳史| 国产精品免费在线免费| 中文字幕在线观看日韩| 欧美噜噜久久久xxx| 在线精品91av| 亚洲直播在线一区| 国产日韩在线视频| 日本中文字幕不卡免费| 在线观看免费高清视频97| 久久久成人精品| 清纯唯美亚洲激情| 国产精品嫩草影院一区二区| 91精品国产成人| 一本色道久久88亚洲综合88| 精品欧美一区二区三区| 亚洲xxxx在线| 自拍视频国产精品| 国产在线拍偷自揄拍精品| 欧美激情视频在线免费观看 欧美视频免费一| 91精品国产综合久久久久久蜜臀| 亚洲r级在线观看| 欧美另类极品videosbest最新版本| 国产综合色香蕉精品| 亚洲精品www久久久久久广东| 久久精品亚洲94久久精品| 国产区精品在线观看| 国产精品男人的天堂| 国产精品视频不卡| 欧美日韩精品在线| 日本免费久久高清视频| 色综合久久悠悠| 欧美大人香蕉在线| 欧美性猛xxx| 欧美在线一级视频| 欧美极品少妇xxxxⅹ喷水| 久久综合免费视频| 日韩av在线免费观看| 成人高清视频观看www| 色琪琪综合男人的天堂aⅴ视频| 久久视频精品在线| 日韩欧美在线中文字幕| 亚洲精品国产电影| 欧美麻豆久久久久久中文| 国产日韩欧美自拍| 亚洲理论在线a中文字幕| 精品日本美女福利在线观看| 国产精品流白浆视频| 日韩va亚洲va欧洲va国产| 欧美日韩人人澡狠狠躁视频| 久久成人在线视频| 黄色精品一区二区| 亚洲欧美日韩久久久久久| 国产精品专区h在线观看| 色综合久综合久久综合久鬼88| 亚洲精品女av网站| 成人免费视频在线观看超级碰| 亚洲qvod图片区电影| 91久久国产综合久久91精品网站| 国产女人18毛片水18精品| 91精品免费久久久久久久久| 亚洲在线观看视频| 一区二区在线视频播放| 亚洲va欧美va在线观看| 欧美区二区三区| 亚洲综合自拍一区| 一本色道久久88综合日韩精品| 91a在线视频| 色综合男人天堂| 国产日韩中文字幕| 午夜精品久久久久久久99热| 亚洲免费电影一区| 日韩国产在线看| 亚洲福利在线播放| 欧美精品在线网站| 欧美激情视频在线免费观看 欧美视频免费一| 日韩av中文字幕在线免费观看| 久久久av亚洲男天堂| 欧美激情视频三区|