今天在网上,看到一篇关于js函数难点的文章,js函数的一些难点。在那上面提了一下,关于js函数返回另一个函数的问题,并附上了一道面试题:

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转过来的,一开始看到那篇文章,我对于返回另一个函数并没有什么认识,我之所以写这篇文章是因为,在那里面有一点让我感到奇怪,那就是最后的调用方式

add(1)(2)(3)

由于在java中,我没有见到过这样的函数调用方式,所以引起了我的注意,我决定去研究研究;下面就将我的研究分享出来,当然如果你对此已经有了深刻的认识,你可以选择跳过,或者对于不足的地方,给出指点 。好了闲话不多说,进入正题。

我们来看一个最简单的例子:

function create1(pro) {console.log("pro : " + pro);return function(obj1, obj2){console.log(obj1 + " -- " + obj2);return obj1 + obj2;}
}

我构建了一个简单的函数create1,并且有一个返回值,返回值是一个内部函数。函数构建完了,接下来进行调用:

var c1 = create1("pro"); // 创建函数

如果按照我之前的理解,当我调用了这个方法后,应该会打印出 pro : pro,接着然后报错的。如果你看完过后,也跟我有一样的想法,那恭喜你想多了或者有了固型思维

。真实的是当我们通过上面的代码调用的时候,日志是打印出了  pro : pro ,但是并没有报错,并且我们反复来回的调用过后,也只是来回的打印相同的日志。这也就说明这个时候,只是进入了create1()方法,并没有进入到该函数的内部函数内。通过面试题的启发,我在试着调用了一次,发现打印出了后续的。

c1(1, 2); // 调用函数

这样就打印出了下面的日志;这说明其实我们一开始调用方法的时候,其实是并没有进入到里层的函数的,只是进入了外层函数体,我们只有再调用才能进入里层函数体,并且这个时候,我们重复上面的调用,他只会是调用里层的函数体,并没有外面的函数体。

类似这种函数返回另一个函数的,我们第一次调用只是构建了一个外层函数体对象,只有有后续的调用,才能调用内层函数体,并且重复调用,只会重复内层函数体。
不要急,还没有完,后面还有……

接下来,我们看一看另一种情况,我们先声明一个函数,用来做加法运算:

function infun(obj1, obj2) {console.log(obj1 + " -- " + obj2);return obj1 + obj2;
}

然后再声明一个函数,在该函数中调用上面声明的函数:

function create2(pro) {console.log("pro = " + pro);return infun(obj1, obj2); // 这个时候,会报错
}

最后是调用:

var c1 = create2("pro"); 

查看日志:

pro = pro
‌Uncaught ReferenceError: obj1 is not defined

会发现,打印出了一条日志后,接着抛出了异常。对方法做一下改动,

function create2(pro) {console.log("pro = " + pro);var obj1 = 1, obj2 = 2;return infun(obj1, obj2); // 这个时候,会报错
}

在调用会发现正常运行,并且打印出了两条日志记录。

这说明,类似于这种,在一个函数内返回一个已经声明的函数,其实是调用已经声明的函数,跟上面的情况是不一样的。
好了,现在回过头来,仔细看看开头的面试题,就会发现一切都明了了:

// 声明一个函数表达式
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()方法
}

然后再来看看调用:

alert(add(1)(2)(3))

结果为6,至于原因就跟我们第一种讨论的情况一样,接下来,我们反复调用:

// 以下结果输出为:6
alert(add(10)(2)(3))
alert(add(100)(2)(3))
// 下面的结果输出变了
alert(add(1)(3)(3))
alert(add(1)(2)(5))

下面附上源码:源码

js函数内返回一个内部函数详解相关推荐

  1. 高阶函数、js函数内返回一个内部函数详解---->函数柯里化

    高阶函数 如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数. 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数. 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函 ...

  2. php function 返回值_PHP函数引用返回的实例详解

    引用返回 手册里是这么写的:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时.不要用返回引用来增加性能,引擎足够聪明来自己进行优化.仅在有合理的技术原因时才返回引用!要返回引用 当你想将函数 ...

  3. JS ES6中export和import详解

    1.Export 模块是独立的文件,该文件内部的所有的变量外部都无法获取.如果希望获取某个变量,必须通过export输出, // profile.js export var firstName = ' ...

  4. (转)C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    原文链接:https://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T ...

  5. JS逆向之浏览器补环境详解

    JS逆向之浏览器补环境详解 "补浏览器环境"是JS逆向者升职加薪的必备技能,也是工作中不可避免的操作. 为了让大家彻底搞懂 "补浏览器环境"的缘由及原理,本文将 ...

  6. 站长在线Python精讲:在Python中函数的定义与创建详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中函数的定义与创建详解>.本文的主要内容有:函数的定义.函数的定义规则.函数的创建. 目录 1.函数的定义 2 ...

  7. c语言flip用法,【杂谈】flip函数介绍与使用方法详解

    实例反转数组中的键名和对应关联的键值:<?php $a1=array("a"=>"red","b"=>"gree ...

  8. JS弹出窗口Window.Open详解

    JS弹出窗口Window.Open详解 一.window.open()支持环境: JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+ 二.基本语法: windo ...

  9. python字符串strip的作用_Python字符串函数strip()原理及用法详解

    Python字符串函数strip()原理及用法详解 strip:用于移除字符串头尾指定的字符(默认为空格)或字符序列.注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符. 语法:str.s ...

最新文章

  1. 编写歌唱比赛评分_【活动】预告||“唱自己的歌”歌唱大赛来啦
  2. Arrays.sort()方法
  3. Jackson ObjectMapper readValue过程
  4. Markdown编辑器:纯前端演示(可接入项目、含源码下载) - 总结篇
  5. 超级计算机开采金矿,中国已知的第一大金矿,储量可达10000吨,全力开采需要40年时间...
  6. 2019.8.21页面功能的实现
  7. 揭秘网络:互联网调查入门 出版发行时间_cqy、cdx、zqsg……啥意思?揭秘QQ上的“00后黑话”...
  8. vue 修改文件怎么启动_Jupyter Notebook如何修改启动时的默认文件路径(Windows系统)...
  9. python保持登录状态_Python-保持登录状态进行接口测试
  10. Linux tmux 使用指南
  11. 美国目前最流行的五种量化交易模型
  12. python偏最小二乘法公式,python3 偏最小二乘法实现
  13. PyCharm安装教程
  14. 分享5款可以录屏的软件,录屏幕视频软件,亲测好用
  15. 直击六大会场 | 洞察100+创新实践,2018TOP100summit圆满落幕!
  16. 江城如画里,山晚望晴空。 两水夹明镜,双桥落彩虹。 人烟寒橘柚,秋色老梧桐。谁念北楼上,临风怀谢公
  17. cid unmatched [object Object] at view.umd.min.js:1 TypeError: Invalid attempt to destructure non-ite
  18. DDIM代码详细解读(3):核心采样代码、超分辨率重建
  19. 个人千元奖励!华秋PCB多层板设计挑战赛等您参与
  20. 假如生活欺骗了你……——网上答疑(14)

热门文章

  1. antd 源码解读 notification
  2. 【人工智能】作业3: Aliens游戏 实验报告
  3. m_p,m_n,CStudent等变量前缀的理解
  4. web前端开发自学难吗,前端开发网上学习
  5. 《CSS禅意花园》翻译完成 Dflying又回来了!
  6. matlab是什么意思,x'在matlab是什么意思
  7. 【陈工笔记】# 汇总人工智能大赛,提升个人竞技能力 #
  8. 论文导读:A Diversity-Promoting Objective Function for Neural Conversation Models
  9. Relative Uncertainty Learning for Facial Expression Recognition
  10. zabbix问题集锦