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

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


        事情的原由:首先我要說的是上一篇博客中我寫到的一句話: 若是使用new關鍵字調用,那麼函數的 return 語句再也不起做用,由於這時還回的是 this 對象。博客發表之後,有網友評論中提到,當使用工廠方法的時候,最後return的是一個對象,並且也確實可以使用這個返回的對象並訪問它的屬性。這就正好和上面說的有衝突了。固然我認可上面的那句話是我在蒐集資料的時候看到的這麼一句話。沒有通過個人驗證,固然我看到「咲臣 」的評論以後我對這句話的正確性進行了詳細的驗證。首先你們看一下這個工廠模式建立js對象。javascript

[javascript] view plain copy print?java

  1. function Person(name,age){  瀏覽器

  2.     var o =new Object();  ide

  3.     o.name=name;  函數

  4.     o.age=age;  測試

  5.     o.getName=function(){  this

  6.         alert(this.name);  spa

  7.     }  .net

  8.     return o;  orm

  9. }  

  10. var person1=new Person("hanyi",22);  

  11. alert(person1.name);  


        運行結果:


在瀏覽器運行時監控person1的結果:



        首先討論一下第10行代碼中new的必要性,這時候咱們想要的結果應該是使person1爲 Person (name,age)函數的返回結果,即對象O(Object)。固然爲了保證正確性咱們也作了驗證把這行代碼改成 :                                                       

[javascript] view plain copy print?

  1. var person1=Person("hanyi1",22);//(爲了區別把字符串稍微改動!)  


        運行結果:



        在瀏覽器運行時監控person1的結果:


        爲了進一步驗證:咱們作如下修改:


[javascript] view plain copy print?

  1. <span style="font-size:18px;"><strong>function Person(name,age){  

  2.     this.a="123";  

  3.     var o =new Object();  

  4.     o.name=name;  

  5.     o.age=age;  

  6.     o.getName=function(){  

  7.         alert(this.name);  

  8.     }  

  9.     return o;  

  10. }  

  11. var person1=new Person("hanyi",22);  

  12. alert(person1.name +"   "+ person1.a);</strong>  

  13. </span>  


即在函數Person(name,age)中添加this.name=name;而後運行看結果。

運行結果:


        在瀏覽器運行時監控person1的結果:



        這個例子能夠清楚的看到,這裏即便使用了new關鍵字,可是Person(name,age)中的return仍是起了做用。並且返回的明顯不是this對象,由於其中不包括a屬性的任何信息。

        經過以上例子徹底能夠說明了上一篇博客對於new關鍵字調用函數與普通方法調用函數的區別的解釋的錯誤性,到如今爲止就證實了個錯誤的觀點,那什麼事正確的觀點呢。是否是若是一個函數中存在return語句,調用這個函數的時候使用new和不使用new返回的結果是同樣的呢?下面咱們再來看看這個例子:


[javascript] view plain copy print?

  1. function Test() {    

  2.   this.name = 'Test';    

  3.   return function() { return true; }    

  4. }    

  5.     

  6. var test = new Test(); // 這裏的 test 是什麼?   



        在瀏覽器運行時監控test的結果:




        最後一行代碼變爲:


[javascript] view plain copy print?

  1. var test = Test(); // 這裏的 test 是什麼?(new去掉)。  



        在瀏覽器運行時監控test的結果:



若是在上面的代碼變爲:


[javascript] view plain copy print?

  1. function Test() {    

  2.   this.name = 'Test';    

  3.   return function() { return true; }    

  4. }   

  5. alert(new Test() == Test() );  



        運行結果:



        以上結果會讓人很迷惑。兩個最後的結果明顯相同,可是爲何真正比較的時候返回的是false呢。由於 JavaScript  對於 Object 和 Function 的比較是基於引用的。

  爲了更清晰的分辨在上述情形下二者間的區別,請繼續看如下代碼


[javascript] view plain copy print?

  1. function Test() {    

  2.   this.name = 'Test';    

  3.   return 'Test';    

  4. }    

  5.     

  6. var fnT = Test();    

  7. var newT = new Test();    



        在瀏覽器運行時監控fnT和newT的結果:



        此次終於有了明顯的區別。顯然,fnT是字符串 Test,那 newT呢?呵呵,是否是被第一個樣例迷惑了?其實,此時newT是一個 Test對象——有一個名爲 name的屬性,其值爲字符串 Test

        經過上面兩段代碼,咱們能夠得出一個猜想,若是函數返回值爲常規意義上的值類型(NumberStringBoolean)時,new函數將會返回一個該函數的實例對象,而若是函數返回一個引用類型(ObjectArrayFunction),則new函數與直接調用函數產生的結果等同。經過在 Test函數中返回不一樣類型的值進行測試,能夠證明這一點。  

        分清這一點,其實仍是蠻重要的,

相關文章
相關標籤/搜索