至少每個嘗試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();