Js的傳回值問題

來源:互聯網
上載者:User
今天看到了網上有一篇關於JS函數傳回值的問題嗎,裡面有一些js函數的痛點。在那上面提了一下,關於js函數返回另一個函數的問題,並附上了一道面試題,我就給大家分享一下

[javascript] view plain copyvar add = function(x){      var sum = 1;      var tmp = function(x){          sum = sum + x;      return tmp;      }      tmp.toString = function(){          return sum;      }      return tmp;  } // alert(add(1)(2)(3)) --> 6

接下來,就來詳細的解讀返回另一個函數的問題。

其實我是從java轉過來的,一開始看到那篇文章,我對於返回另一個函數並沒有什麼認識,我之所以寫這篇文章是因為,在那裡面有一點讓我感到奇怪,那就是最後的調用方式

[javascript] view plain copy

add(1)(2)(3)

由於在java中,我沒有見到過這樣的函數調用方式,所以引起了我的注意,我決定去研究研究;下面就將我的研究分享出來,當然如果你對此已經有了深刻的認識,你可以選擇跳過,或者對於不足的地方,給出指點微笑。好了閑話不多說,進入正題。

我們來看一個最簡單的例子:

[javascript] view plain copyfunction create1(pro) {      console.log("pro : " + pro);      return function(obj1, obj2){          console.log(obj1 + " -- " + obj2);          return obj1 + obj2;      }  }

我構建了一個簡單的函數create1,並且有一個傳回值,傳回值是一個內建函式。函數構建完了,接下來進行調用:

[javascript] view plain copyvar c1 = create1("pro"); // 建立函數

如果按照我之前的理解,當我調用了這個方法後,應該會列印出 pro : pro,接著然後報錯的。如果你看完過後,也跟我有一樣的想法,那恭喜你想多了或者有了固型思維微笑

。真實的是當我們通過上面的代碼調用的時候,日誌是列印出了 pro : pro ,但是並沒有報錯,並且我們反覆來回的調用過後,也只是來回的列印相同的日誌。這也就說明這個時候,只是進入了create1()方法,並沒有進入到該函數的內建函式內。通過面試題的啟發,我在試著調用了一次,發現列印出了後續的。

[java] view plain copyc1(1, 2); // 調用函數

這樣就列印出了下面的日誌;這說明其實我們一開始調用方法的時候,其實是並沒有進入到裡層的函數的,只是進入了外層函數體,我們只有再調用才能進入裡層函數體,並且這個時候,我們重複上面的調用,他只會是調用裡層的函數體,並沒有外面的函數體。

類似這種函數返回另一個函數的,我們第一次調用只是構建了一個外層函數體對象,只有有後續的調用,才能調用內層函數體,並且重複調用,只會重複內層函數體。

不要急,還沒有完,後面還有……

接下來,我們看一看另一種情況,我們先聲明一個函數,用來做加法運算:

[javascript] view plain copyfunction infun(obj1, obj2) {      console.log(obj1 + " -- " + obj2);          return obj1 + obj2;  }  然後再聲明一個函數,在該函數中調用上面聲明的函數:[javascript] view plain copyfunction create2(pro) {      console.log("pro = " + pro);          return infun(obj1, obj2); // 這個時候,會報錯  }

最後是調用:

[javascript] view plain copyvar c1 = create2("pro");

查看日誌:

pro = proUncaught ReferenceError: obj1 is not defined

會發現,列印出了一條日誌後,接著拋出了異常。對方法做一下改動,

[javascript] view plain copyfunction create2(pro) {      console.log("pro = " + pro);      var obj1 = 1, obj2 = 2;      return infun(obj1, obj2); // 這個時候,會報錯  }

在調用會發現正常運行,並且列印出了兩條日誌記錄。

這說明,類似於這種,在一個函數內返回一個已經聲明的函數,其實是調用已經聲明的函數,跟上面的情況是不一樣的。

好了,現在回過頭來,仔細看看開頭的面試題,就會發現一切都明了了:

[javascript] view plain copy// 聲明一個函數運算式  var add = function(x){      var sum = 1;      // 在函數運算式內部有一個求和的內建函式      var tmp = function(x){          sum = sum + x;// 求和          return tmp;      }      // 構建一個函數體的toString()函數      tmp.toString = function(){          return sum;      }      return tmp; // 返回的是一個函數體,如果該函數體有toString()方法,則會調用函數體的toString()方法  }

然後再來看看調用:

[javascript] view plain copyalert(add(1)(2)(3))

結果為6,至於原因就跟我們第一種討論的情況一樣,接下來,我們反覆調用:

[javascript] view plain copy// 以下結果輸出為:6  alert(add(10)(2)(3))  alert(add(100)(2)(3))  // 下面的結果輸出變了  alert(add(1)(3)(3))  alert(add(1)(2)(5))

相信看了這些案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!


相關閱讀:

怎樣讓DIV自適應高度

怎樣用CSS隱藏圖片背景的文字內容

在HTML裡用CSS隱藏div的方法

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.