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

首頁 > 編程 > JavaScript > 正文

深入理解JavaScript編程中的原型概念

2019-11-20 12:09:30
字體:
來源:轉載
供稿:網友

 JavaScript 的原型對象總是讓人糾結。即使是經驗豐富的JavaScript專家甚至其作者,經常對這一概念給出很有限的解釋。我相信問題來自于我們對原型最早的認識。原型總是與new, constructor 以及令人困惑的prototype屬性緊密聯系。事實上,原型是一個相當簡單的概念。為了更好地理解它,我們需要忘記我們所‘學到'的構造原型,然后,追本溯源。

什么是原型?

原型是一個從其他對象繼承屬性的對象。

是不是任何對象都可以是原型?

是的

那些對象有原型?

每個對象都有一個默認的原型。原型本身就是對象,每一個原型本身也存在一個原型。(只有一個例外,默認的對象原型在每條原型鏈的頂端,其他的原型在原型鏈的后面)

退一步說,什么又是對象呢?

在JavaScript中一個對象是以鍵值對保存的任意的無序集合,如果它不是原始類(undefined,null,boolean.nuber或string),它就是一個對象。

你可以認為每個對象都有一個prototype. 但當我寫({}).prototype的時候,我卻得到了undefined,你瘋不瘋?

忘記你所掌握的關于prototype屬性的理解 - 這很可能是迷惑的根源. 一個對象真正的prototype是內部[[Prototype]]屬性. ECMA 5介紹了標準的訪問方法,Object.getPrototypeOf(object)。這個最新的實現已被Firefox, Safari, Chrome and IE9所支持. 另外,除了IE,所有的瀏覽器都支持非標準的訪問方法__proto__.不然的話,我們只能說對象的構造方法就是它的prototype屬性.
 

var a = {}; //Opera 或 IE<=8下失敗Object.getPrototypeOf(a); //[object Object] //IE下失敗a.__proto__; //[object Object] //所有瀏覽器//(but only if constructor.prototype has not been replaced and fails with Object.create)a.constructor.prototype; //[object Object]


很好, false 是原始類型, 為什么false.__proto__ 會返回一個值呢?

當訪問原始類型的原型(prototype),它會強制轉化為一個對象。
 

//(works in IE<=8 too, due to double-negative)false.__proto__ === Boolean(false).__proto__; //true

我想使用原型實現繼承,我現在該怎么做?

給一個實例添加原型屬性,幾乎是沒有意義的.除非一種情況,那就是,很有效率的添加屬性直接到實例本身.假設我們已經有了一個對象,要共享已經存在的對象的功能.例如Array,我們可以這樣做
 

//fails in IE<=8var a = {};a.__proto_ = Array.prototype;a.length; //0

但是我們可以看到原型的真正強大在于多個實例共享同一原型。原型對象的屬性只被定義一次就可以被它引用的所有實例所繼承。使用原型對性能和程序可維護性的提高效果是很顯而易見的。那么這就是構造函數產生的原因嗎?是的,構造函數提供了一個便捷的跨瀏覽器機制來實現對實例創建時的公用原型分配。。


在給出一個例子之前,我需要知道constructor.prototype property是干什么的?

好吧,首先,JavaScript不區分構造函數和其它方法,所以每個方法都有prototype屬性。反而任何不是方法的,都沒有這樣的屬性。
 

//永遠不是構造函數的方法,無論如何都是有prototype屬性的Math.max.prototype; //[object Object] //構造函數也有prototype屬性var A = function(name) {  this.name = name;}A.prototype; //[object Object] //Math不是一個方法,所以沒有prototype屬性Math.prototype; //null

現在可以定義: 一個方法的prototype屬性是當這個方法被用作構造函數來創建實例時賦給該實例的prototype的對象。

非常重要的一點是,要理解方法的prototype屬性和實際的prototype沒有任何關系。
 

//(在IE中會失敗)var A = function(name) {  this.name = name;} A.prototype == A.__proto__; //falseA.__proto__ == Function.prototype; //true - A的prototype是它的構造函數的prototype屬性

能給個例子不?

以下的代碼,可能你已經看到或用過上百次了,但這里又把它搬上來了,但可能會有些新意。
 

//構造器. <em>this</em> 作為新對象返回并且它內部的[[prototype]]屬性將被設置為構造器默認的prototype屬性var Circle = function(radius) {  this.radius = radius;  //next line is implicit, added for illustration only  //this.__proto__ = Circle.prototype;} //擴充 Circle默認的prototype對象的屬性因此擴充了每個由它新建實例的prototype對象的屬性Circle.prototype.area = function() {  return Math.PI*this.radius*this.radius;} //創建Circle的兩個示例,每個都會使用相同的prototype屬性var a = new Circle(3), b = new Circle(4);a.area().toFixed(2); //28.27b.area().toFixed(2); //50.27

這很棒。如果我改變了constructor的prototype屬性,即使是已存在的實例對象也可以立刻訪問新的prototype版本嗎?

嗯......不完全是。如果我修改的是現存prototype的屬性后,那么確實是這種情況,因為對象創建時a.__proto__引用了A.prototype所定義的對象。
 

var A = function(name) {  this.name = name;} var a = new A('alpha');a.name; //'alpha' A.prototype.x = 23; a.x; //23


但是如果我將prototype屬性用一個新對象代替,a.__proto__ 仍然指向原始對象。
 

var A = function(name) {  this.name = name;} var a = new A('alpha');a.name; //'alpha' A.prototype = {x:23}; a.x; //null

一個缺省的prototype是什么樣的?

一個擁有constructor屬性的對象。
 

var A = function() {};A.prototype.constructor == A; //true var a = new A();a.constructor == A; //true (a 的constructor屬性繼承自它的原型)


instanceof與prototype有啥關系?
如果A的prototype屬性出現在a的原型鏈中,則表達式a instanceof A會返回true。這意味著我們可以欺騙instanceof,讓它失效。
 

var A = function() {} var a = new A();a.__proto__ == A.prototype; //true - so instanceof A will return truea instanceof A; //true; //mess around with a's prototypea.__proto__ = Function.prototype; //a's prototype no longer in same prototype chain as A's prototype propertya instanceof A; //false


那么我還能利用原型干些其它的什么事兒?

記得我曾經說過每一個構造器都擁有一個prototype屬性,利用該屬性可以將原型賦值給所有由構造器產生的實例?其實這同樣適用于本地構造器,例如Function和String。通過擴展(而不是替換)這個屬性,我們可以更新每個指定類型對象的prototype。 

String.prototype.times = function(count) {  return count < 1 ? '' : new Array(count + 1).join(this);} "hello!".times(3); //"hello!hello!hello!";"please...".times(6); //"please...please...please...please...please...please..."

告訴我更多關于繼承與原型是怎么工作的。原型鏈又是什么東東?


因為每個對象和每個原型(本身)都有一個原型,我們可以想象, 一個接一個的對象連接在一起形成一個原型鏈。 原型鏈的終端總是默認對象(object)的原型。
 

a.__proto__ = b;b.__proto__ = c;c.__proto__ = {}; //默認對象{}.__proto__.__proto__; //null


原型繼承機制是內在且隱式實現的。當對象a要訪問屬性foo時,Javascript會遍歷a的原型鏈(首先從a自身開始),檢查原型鏈的每一個環節中存在的foo屬性。如果找到了foo屬性就會將其返回,否則返回undefined值。

直接賦值會咋樣?

當直接為對象屬性賦值時,原型繼承機制就玩不轉了。a.foo='bar'會直接賦值給a的foo屬性。要想為原型對象的屬性賦值,你需要直接定位原型對象的該屬性。
關于javascript原型就講全了。我覺得對于原型概念的理解,我把握的還是比較準確的,但是我的觀點無論如何也不是最后的結果。請隨便告之我的錯誤之處或提出和我不一致的觀點。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲高清免费观看高清完整版| 伊人久久久久久久久久久久久| 亚洲精品www久久久| 久久亚洲精品视频| 亚洲性无码av在线| 最新91在线视频| 国产精品va在线播放| 久久久精品免费| 成人情趣片在线观看免费| 日韩中文理论片| 亚洲男女自偷自拍图片另类| 亚洲欧美福利视频| 91精品国产综合久久香蕉| 久久国产精品久久久久久| 国产69精品久久久久9999| 最近2019中文字幕一页二页| 国产成人av网址| 国产中文字幕91| 久久好看免费视频| 久久久久久香蕉网| 欧美视频专区一二在线观看| 色爱精品视频一区| 亚洲91av视频| 久久久精品久久久| 国产精品日韩欧美大师| 国产精品丝袜白浆摸在线| 亚洲美女激情视频| 亚洲热线99精品视频| 亚洲欧美日韩中文在线| 国产精品成人在线| 性欧美长视频免费观看不卡| 久久久久成人精品| 国产成人免费91av在线| 成人精品视频久久久久| 91av在线网站| 91午夜理伦私人影院| 久久影视电视剧凤归四时歌| 亚洲欧美另类中文字幕| 综合网中文字幕| 午夜精品久久久久久久男人的天堂| 日本高清视频一区| 欧美成人激情视频免费观看| xvideos亚洲| 国产香蕉精品视频一区二区三区| 亚洲视频在线免费看| 欧美性生活大片免费观看网址| 国产精品久久久91| 成人信息集中地欧美| 日韩大片免费观看视频播放| 国产精品极品在线| 国产精品久久久久久久久久久久久久| 亚洲xxxx妇黄裸体| 国产不卡视频在线| 国产精品久久久久久久app| 欧美成人网在线| 成人黄色影片在线| 亚洲精品美女免费| 一个人看的www久久| 欧美国产精品人人做人人爱| 中文字幕日韩在线播放| 国产欧美日韩中文字幕在线| 国产精品久久久久久久久久小说| 精品国产欧美成人夜夜嗨| 亚洲精品久久久久久下一站| 国产色视频一区| 九九九热精品免费视频观看网站| 亚洲国产毛片完整版| 亚洲欧美日韩一区在线| 国产精品久久999| 亚洲自拍av在线| 韩国19禁主播vip福利视频| 亚洲国产日韩欧美在线99| 久久精品国产精品亚洲| 欧美一级淫片videoshd| 国产成人精品av在线| 日韩av电影免费观看高清| 久久亚洲成人精品| 国产激情视频一区| 日韩欧美在线中文字幕| 国产精品美女在线观看| 日韩一区在线视频| 国产日本欧美一区二区三区| 久久av在线播放| 91超碰中文字幕久久精品| 欧美激情亚洲一区| 欧美日韩国产第一页| 日韩免费观看网站| 久久久久国产精品免费| 亚洲美女av电影| 一区二区三区高清国产| 在线一区二区日韩| 日韩av中文字幕在线播放| 欧美性xxxx极品高清hd直播| 国产精品啪视频| 国产一区玩具在线观看| 成人网在线观看| 亚洲伊人久久综合| 91久久中文字幕| 欧美国产日韩中文字幕在线| 国产91精品久久久久久久| 懂色av影视一区二区三区| 欧美精品一区二区免费| 亚洲www永久成人夜色| 日韩中文字幕不卡视频| 亚洲国模精品私拍| 亚洲tv在线观看| 全亚洲最色的网站在线观看| 欧美一级视频免费在线观看| 91久热免费在线视频| 26uuu另类亚洲欧美日本一| 亚洲视频电影图片偷拍一区| 日韩精品免费电影| 日韩av中文字幕在线播放| 久久精品国产久精国产一老狼| 国模吧一区二区| 欧美激情国产日韩精品一区18| 狠狠躁天天躁日日躁欧美| 欧美日韩免费在线| 国产精品流白浆视频| 亚洲精品国产精品国产自| 亚洲视频一区二区三区| 欧美日韩国产在线| 成人网在线视频| 青青草一区二区| 国内精品久久久久久| 色播久久人人爽人人爽人人片视av| 91av在线免费观看视频| 91在线观看免费观看| 日本精品视频网站| 久久久www成人免费精品| 国产精品老牛影院在线观看| 国产欧美日韩中文字幕在线| 日韩精品视频在线观看网址| 久热精品视频在线观看| 欧美插天视频在线播放| 亚洲第一网中文字幕| 欧美日韩ab片| 亚州欧美日韩中文视频| 国产亚洲欧洲高清| 久久久噜噜噜久久久| 国产91免费观看| 国产精品情侣自拍| 亚洲视频999| 亚洲成人激情在线观看| 国产一区二区香蕉| 国产噜噜噜噜噜久久久久久久久| 国产精品欧美一区二区| 欧美国产精品日韩| 中文字幕免费精品一区高清| 久久夜色撩人精品| 成人欧美一区二区三区在线湿哒哒| 91亚洲精品一区| 91wwwcom在线观看| 国产精品色悠悠| 91久久久久久久一区二区| 久久777国产线看观看精品| 国产精品久久久久国产a级| 中文字幕亚洲第一| 日韩在线观看你懂的| 欧美精品videosex性欧美| 日韩亚洲精品电影| 精品视频在线播放| 97久久精品人人澡人人爽缅北| 欧美性极品少妇精品网站|