天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

JavaScript constructor和instanceof,JSOO中的一對歡喜冤家

至少每個嘗試JavaScriptOO的程序員都花費很多精力用在面向對象機制的模擬上而非業務本身.
這對Java,C++甚至php的開發者來講都是難以想象的.
更糟糕的是模擬OO對于JavaScript高級程序員都有著邪惡的吸引.
因為干這個事兒超然于業務之上,有種創造新編程語言一般的快感,可以令IQ盡情揮灑.
正如前些年大家都想把自個網站的common.js寫成個框架一樣.直到YUI,JQuery等等的強勢推出才稍有平息.
然而雖然各個框架都有對JavaScriptOO模擬,但還未到有誰誰誰可以一桶糨糊的時候吧.
或許江湖就不需要的霸主出現,抑或大家只要等到JS2.0+就好了.
如果說可以new就是面向對象,那顯然JavaScript在這方面是非常不錯的.
復制代碼 代碼如下:
function Person(name){
this.name = name;
}
var lenel = new person("lenel");
alert(lenel.constructor === Person);
alert(lenel instanceof Person === true);
alert(lenel instanceof Object === true);

到此為止,一切都很和諧.
對象的constructor正如字面上的意義指向構造它的Person.
對象是構造它的Person的一個實例(instance).
所有對象都是Object的實例,像極了Java.
JavaScript提供原型(prototype)的方式來實現方法拓展和繼承
復制代碼 代碼如下:
Person.prototype.getName = function(){
return this.name
};

這樣定義了之后所有對象都具有了getName的方法.
當然也可以將寫在對象構造時
復制代碼 代碼如下:
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
};
}

但是這種做法不僅是帶來額外性能損耗這點瑕疵,也不僅是帶來了可以訪問私有變量的特權.
它與使用prototype的寫法還會其他有不同之處,不過這不是本文的重點.
接下來,我們想到繼承,很常見的寫法是這樣的.
復制代碼 代碼如下:
function Stuff(name,id){
this.name = name;
this.id = id;
}
Stuff.prototype = new Person();
var piupiu = new Stuff("piupiu","007");
alert(piupiu.getName());

非常好,繼承了getName方法;
考察下instanceof
復制代碼 代碼如下:
alert(piupiu instanceof Stuff === true);
alert(piupiu instanceof Person === true);

非常好,說明了Stuff和Person是有關系的.piupiu是它倆的實例,非常Java.
接下來再考察下constructor
復制代碼 代碼如下:
alert(piupiu.constructor === Stuff);//false
test(piupiu.constructor === Person);//true

問題出現了明明new的Stuff為啥constructor卻是Person,
在這兒將道理也是強詞奪理,我們只好記住結論
結論:對象的constructor屬性并非指向其構造器,而是指向其構造器的prototype屬性的constructor屬性
文字功底太差,自己讀過都覺得沒說清楚
放在這里:
對象piupiu的constructor屬性指向的是其構造器Stuff的prototype屬性的constructor屬性
因為Stuff.prototype = new Person();
所以Stuff.prototype.constructor === Person.
所以piupiu.consturctor === Person.
以上的結論不僅僅在對象繼承的時候才出現,在定義對象時
復制代碼 代碼如下:
function Student(name){
this.name = name;
}
Student.prototype = {
getName:function(){
return this.name;
},
setName:function(name){
this.name = name;
}
}

如果方法比較多,常常會這樣寫,看起來規矩一些.
其實這種寫法同樣犧牲了constructor
復制代碼 代碼如下:
var moen = new Student("moen");
alert(moen.constructor === Student);//false
alert(moen.constructor === Object);//true

因為在{}相當于new Object(),所以根據上面的結論prototype={}時,constructor變了.
保衛constructor!繼承時我們用一個循環來把父類的方法copyto子類
復制代碼 代碼如下:
function Stuff1(name,id){
this.name = name;
this.id = id;
}
for(var fn in Person.prototype){
Stuff1.prototype[fn] = Person.prototype[fn];
}
var piupiu1 = new Stuff1("piupiu1","008");
alert(piupiu1.getName() === "piupiu1");
alert(piupiu1.constructor === Stuff1);

It works!當我們興沖沖的把父類的方法都繼承下來的時候,我們卻丟失了父子關系.
復制代碼 代碼如下:
alert(piupiu1 instanceof Stuff1 === true);//true
alert(piupiu1 instanceof Person === true);//false

顯然,我們沒有說過Stuff1是繼承至Person啊,只一個for循環能說明什么呢.
這好像是一對矛盾..顧此必失彼.
所以叻,深入使用對象的時候,甚至你一不小心,都會讓instantceof和constructor丟去字面的含義.
所以叻,在使用框架的時候,如果提供了繼承功能,如果不試不會知道你為了繼承放棄了哪個.
所以叻,模擬OO時就必須要提供替代這兩個字面含義的屬性或方法的實現,而且必須讓使用者知道!
模擬OO絕對不只這個問題,在子類方法中調用父類的同名方法,這個OO語言常見的特性,
JavaScript實現起來也非常困難,大師們基本都有各自的一套,只不過有些用心去做了用起來相比之下更自然些,如Base庫.
當然可以摒棄instanceof和constructor的使用,就當不知道有這么一回兒事兒,活兒仍可繼續,死不了人的.
但如果你不是單槍匹馬作戰,那就通知你的Partner也摒棄這對冤家吧.
類似今天這點事兒,老鳥們都清楚的很,但如果不是團隊中每個人都有統一的認識,那就是隱患.
一個好玩兒的現象<<JavaScript高級程序設計>>強調instanceof,而<<精通JavaScript>>強調constructor.而各自對另一個一筆帶過或只字不提.怨念..甚深...

JavaScript技術JavaScript constructor和instanceof,JSOO中的一對歡喜冤家,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 牛牛在线视频 | 国产性夜夜春夜夜爽1A片 | 亲嘴扒胸摸屁股视频免费网站 | 国产成人无码WWW免费视频在线 | 狠狠色狠狠色综合日日32 | 久久热免费视频 | 美女洗澡脱得一二干净 | 色狠狠色狠狠综合天天 | 日韩人妻少妇一区二区三区 | 日韩在线av免费视久久 | 亚洲精品色播一区二区 | 新金梅瓶玉蒲团性奴3 | 全肉高H短篇合集 | 午夜福利体验免费体验区 | 色尼玛亚洲综合 | 国产一级特黄aa毛片 | 久久伊人久久 | 在线免费观看国产 | 久久99国产视频 | 蜜桃传媒在线播放 | 黄色三级在线观看 | 国产树林野战在线播放 | 色多多污网站在线观看 | 午夜国产免费视频亚洲 | 97超碰97资源在线观看视频 | 色视频色露露永久免费观看 | 91麻豆国产精品91久久久 | 无人影院在线播放 | 国产亚洲精品久久久999蜜臀 | 亚洲精品拍拍央视网出文 | 性绞姿始动作动态图 | 入禽太深在线观看免费高清 | 浪荡受自我调教纯肉BL | 伦理片 a在线线版韩国 | 国产亚洲tv在线观看 | 奶头从情趣内衣下露了出来AV | bl 纯肉 高Hbl被强文 | 国拍在线精品视频免费观看 | 99久久免费看少妇高潮A片 | 他揉捏她两乳不停呻吟口述 | 老色69久久九九精品高潮 |