Js New一個函數和直接調用的區別

事情的起因:首先我要說的是上一篇博客中我寫到的一句話: 如果使用new關鍵字調用,那麼函數的 return 語句不再起作用,因爲這時還回的是 this 對象。博客發表以後,有網友評論中提到,當使用工廠方法的時候,最後return的是一個對象,而且也確實能夠使用這個返回的對象並訪問它的屬性。這就正好和上面說的有衝突了。當然我承認上面的那句話是我在蒐集資料的時候看到的這麼一句話。沒有經過我的驗證,當然我看到“咲臣 ”的評論之後我對這句話的正確性進行了詳細的驗證。首先大家看一下這個工廠模式創建js對象。
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函數中返回不同類型的值進行測試,可以證實這一點。  

分清這一點,其實還是蠻重要的,至少在看一些面向對象的框架類庫代碼時,會少一些疑惑。(再次感謝網友“咲臣 ”讓我從思考中又一次收穫了很多,當然也感謝其他朋友對我的博客給出意見和建議。).


發佈了69 篇原創文章 · 獲贊 7 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章