今天看到網路上有一篇關於JS函數回傳值的問題了嗎,裡面有一些js函數的困難點。在那上面提了一下,關於js函數返回另一個函數的問題,並附上了一道面試題,我就給大家分享一下
[javascript] view plain copy var 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 copy function create1(pro) { console.log("pro : " + pro); return function(obj1, obj2){ console.log(obj1 + " -- " + obj2); return obj1 + obj2; } }
我建立了一個簡單的函數create1,並且有一個回傳值,回傳值是一個內部函數。函數建構完了,接下來進行呼叫:
[javascript] view plain copy var c1 = create1("pro"); // 创建函数
如果按照我之前的理解,當我呼叫了這個方法後,應該會印出 pro : pro,接著然後報錯的。如果你看完過後,也跟我有一樣的想法,那恭喜你想太多了或者有了固型思維微笑
#。真實的是當我們透過上面的程式碼呼叫的時候,日誌是打印出了 pro : pro ,但是並沒有報錯,並且我們反覆來回的調用過後,也只是來回的打印相同的日誌。這也就說明這個時候,只是進入了create1()方法,並沒有進入到該函數的內部函數內。透過面試題的啟發,我在試著調用了一次,發現印出了後續的。
[java] view plain copy c1(1, 2); // 调用函数
這樣就列印出了下面的日誌;這說明其實我們一開始呼叫方法的時候,其實是並沒有進入到裡層的函數的,只是進入了外層函數體,我們只有再呼叫才能進入裡層函數體,而這個時候,我們重複上面的調用,他只會是調用裡層的函數體,並沒有外面的函數體。
類似這種函數返回另一個函數的,我們第一次調用只是構建了一個外層函數體對象,只有有後續的調用,才能調用內層函數體,並且重複調用,只會重複內層函數體。
不要急,還沒完,後面還有…
接下來,我們看另一種情況,我們先宣告一個函數,用來做加法運算:
[javascript] view plain copy function infun(obj1, obj2) { console.log(obj1 + " -- " + obj2); return obj1 + obj2; } 然后再声明一个函数,在该函数中调用上面声明的函数: [javascript] view plain copy function create2(pro) { console.log("pro = " + pro); return infun(obj1, obj2); // 这个时候,会报错 }
最後是呼叫:
[javascript] view plain copy var c1 = create2("pro");
查看日誌:
pro = pro Uncaught ReferenceError: obj1 is not defined
會發現,印出了一條日誌後,接著拋出了例外。對方法做一下改動,
[javascript] view plain copy function 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 copy alert(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中文網其它相關文章!
相關閱讀:
#以上是Js的回傳值問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版
好用的JavaScript開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。