事情的原由:首先我要說的是上一篇博客中我寫到的一句話: 若是使用new關鍵字調用,那麼函數的 return 語句再也不起做用,由於這時還回的是 this 對象。博客發表之後,有網友評論中提到,當使用工廠方法的時候,最後return的是一個對象,並且也確實可以使用這個返回的對象並訪問它的屬性。這就正好和上面說的有衝突了。固然我認可上面的那句話是我在蒐集資料的時候看到的這麼一句話。沒有通過個人驗證,固然我看到「咲臣 」的評論以後我對這句話的正確性進行了詳細的驗證。首先你們看一下這個工廠模式建立js對象。javascript
[javascript] view plain copy print?java
function Person(name,age){ 瀏覽器
var o =new Object(); ide
o.name=name; 函數
o.age=age; 測試
o.getName=function(){ this
alert(this.name); spa
} .net
return o; orm
}
var person1=new Person("hanyi",22);
alert(person1.name);
運行結果:
在瀏覽器運行時監控person1的結果:
首先討論一下第10行代碼中new的必要性,這時候咱們想要的結果應該是使person1爲 Person (name,age)函數的返回結果,即對象O(Object)。固然爲了保證正確性咱們也作了驗證把這行代碼改成 :
[javascript] view plain copy print?
var person1=Person("hanyi1",22);//(爲了區別把字符串稍微改動!)
運行結果:
在瀏覽器運行時監控person1的結果:
爲了進一步驗證:咱們作如下修改:
[javascript] view plain copy print?
<span style="font-size:18px;"><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>
</span>
即在函數Person(name,age)中添加this.name=name;而後運行看結果。
運行結果:
在瀏覽器運行時監控person1的結果:
這個例子能夠清楚的看到,這裏即便使用了new關鍵字,可是Person(name,age)中的return仍是起了做用。並且返回的明顯不是this對象,由於其中不包括a屬性的任何信息。
經過以上例子徹底能夠說明了上一篇博客對於new關鍵字調用函數與普通方法調用函數的區別的解釋的錯誤性,到如今爲止就證實了個錯誤的觀點,那什麼事正確的觀點呢。是否是若是一個函數中存在return語句,調用這個函數的時候使用new和不使用new返回的結果是同樣的呢?下面咱們再來看看這個例子:
[javascript] view plain copy print?
function Test() {
this.name = 'Test';
return function() { return true; }
}
var test = new Test(); // 這裏的 test 是什麼?
在瀏覽器運行時監控test的結果:
最後一行代碼變爲:
[javascript] view plain copy print?
var test = Test(); // 這裏的 test 是什麼?(new去掉)。
在瀏覽器運行時監控test的結果:
若是在上面的代碼變爲:
[javascript] view plain copy print?
function Test() {
this.name = 'Test';
return function() { return true; }
}
alert(new Test() == Test() );
運行結果:
以上結果會讓人很迷惑。兩個最後的結果明顯相同,可是爲何真正比較的時候返回的是false呢。由於 JavaScript 對於 Object 和 Function 的比較是基於引用的。
爲了更清晰的分辨在上述情形下二者間的區別,請繼續看如下代碼:
[javascript] view plain copy print?
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函數中返回不一樣類型的值進行測試,能夠證明這一點。
分清這一點,其實仍是蠻重要的,