function Person(name,age){
var o =new Object();
o.name=name;
o.age=age;
o.getName=function(){
alert(this.name);
}
return o;
}
var person1=new Person("hanyi",22);
alert(person1.name);
運行結果:
在瀏覽器運行時監控person1的結果:
首先討論一下第10行代碼中new的必要性,這時候我們想要的結果應該是使person1爲 Person (name,age)函數的返回結果,即對象O(Object)。當然爲了保證正確性我們也做了驗證把這行代碼改爲 :
var person1=Person("hanyi1",22);//(爲了區別把字符串稍微改動!)
運行結果:
在瀏覽器運行時監控person1的結果:
爲了進一步驗證:我們做以下修改:
<strong>function Person(name,age){
this.a="123";
var o =new Object();
o.name=name;
o.age=age;
o.getName=function(){
alert(this.name);
}
return o;
}
var person1=new Person("hanyi",22);
alert(person1.name +" "+ person1.a);</strong>
即在函數Person(name,age)中添加this.name=name;然後運行看結果。
運行結果:
在瀏覽器運行時監控person1的結果:
這個例子可以清楚的看到,這裏即使使用了new關鍵字,但是Person(name,age)中的return還是起了作用。而且返回的明顯不是this對象,因爲其中不包括a屬性的任何信息。
通過以上例子完全可以說明了上一篇博客對於new關鍵字調用函數與普通方法調用函數的區別的解釋的錯誤性,到現在爲止就證明了個錯誤的觀點,那什麼事正確的觀點呢。是不是如果一個函數中存在return語句,調用這個函數的時候使用new和不使用new返回的結果是一樣的呢?下面我們再來看看這個例子:
function Test() {
this.name = 'Test';
return function() { return true; }
}
var test = new Test(); // 這裏的 test 是什麼?
在瀏覽器運行時監控test的結果:
如果在上面的代碼變爲:
function Test() {
this.name = 'Test';
return function() { return true; }
}
alert(new Test() == Test() );
運行結果:
以上結果會讓人很迷惑。兩個最後的結果明顯相同,但是爲什麼真正比較的時候返回的是false呢。因爲 Javascript 對於 Object 和 Function 的比較是基於引用的。
爲了更清晰的分辨在上述情形下兩者間的區別,請繼續看以下代碼:
function Test() {
this.name = 'Test';
return 'Test';
}
var fnT = Test();
var newT = new Test();
在瀏覽器運行時監控fnT和newT的結果:
這次終於有了明顯的區別。顯然,fnT是字符串 Test,那 newT呢?呵呵,是不是被第一個樣例迷惑了?其實,此時 newT是一個 Test對象——有一個名爲 name的屬性,其值爲字符串 Test。
通過上面兩段代碼,我們可以得出一個猜測,如果函數返回值爲常規意義上的值類型(Number、String、Boolean)時,new函數將會返回一個該函數的實例對象,而如果函數返回一個引用類型(Object、Array、Function),則new函數與直接調用函數產生的結果等同。通過在 Test函數中返回不同類型的值進行測試,可以證實這一點。
分清這一點,其實還是蠻重要的,至少在看一些面向對象的框架類庫代碼時,會少一些疑惑。(再次感謝網友“咲臣 ”讓我從思考中又一次收穫了很多,當然也感謝其他朋友對我的博客給出意見和建議。).