ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

现代 JavaScript 教程练习精讲:用闭包实现双括号调用 `sum(a)(b)`

现代 JavaScript 教程练习精讲:用闭包实现双括号调用 `sum(a)(b)` 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本篇指南基于《现代 JavaScript 教程》The Modern JavaScript Tutorial中文仓库中的闭包 sum练习任务题目 与 官方解答系统讲解如何编写一个支持sum(a)(b) ab双括号调用的sum函数。文章将结合变量作用域与闭包主教程中的词法环境Lexical Environment与[[Environment]]原理剖析这类返回函数写法背后的闭包机制读完你不仅能独立完成该练习还能举一反三地理解柯里化风格调用、计数器makeCounter等常见闭包模式。练习目标让函数支持两次调用题目要求非常简短编写一个像sum(a)(b) ab这样工作的sum函数——是的就是这种通过双括号的方式并不是错误。即调用一次sum(a)之后紧接着再调用一次返回结果两次括号分别接收一个参数最终完成两个参数的加法。预期的行为如下sum(1)(2) 3 sum(5)(-1) 4该练习在原仓库中被标记为importance: 4重要度较高位于闭包章节的练习题序列中是检验读者是否真正理解函数可以返回函数、内部函数可以访问外部变量这一核心知识的经典入门题。核心思路第一个括号必须返回一个函数要使sum(a)(b)这种写法成立关键推理只有一步sum(a)的结果必须是一个函数这样紧接着的(b)才能被当作一次函数调用。JavaScript 中的函数是一等公民可以像普通值一样被返回因此我们完全可以写出返回函数的函数。按照官方解答的思路为了让第二个括号有效第一个括号必须返回一个函数function sum(a) { return function(b) { return a b; // 从外部词法环境获得 a }; } alert( sum(1)(2) ); // 3 alert( sum(5)(-1) ); // 4逐步拆解执行过程sum(1)被调用参数a被赋值为1sum内部返回了一个新的匿名函数function(b) { return a b; }紧接着的(2)就是对这个返回函数的调用参数b被赋值为2匿名函数体中的a并不是它自己的局部变量而是来自外层sum调用的词法环境通过闭包机制仍然可访问于是计算出1 2 3。同理sum(5)(-1)中a 5、b -1最终得到4。原理深挖为什么内部函数还能访问a初看之下读者最容易困惑的点是sum调用结束后参数a不是应该消失了吗为什么返回的内部函数还能读到它答案在于 JavaScript 的词法环境Lexical Environment与函数隐藏属性[[Environment]]。根据闭包主教程的讲解每次函数调用开始时都会自动创建一个新的词法环境对象用于存储该次调用的局部变量和参数每个函数在诞生时都会通过隐藏属性[[Environment]]记住创建它的词法环境的引用且该引用在创建时被设置并永久保存当代码访问一个变量时会先搜索内部词法环境找不到再顺着对外部词法环境的引用逐层向外查找直到全局词法环境。回到本题sum(1)的调用创建了一个词法环境其中记录了a 1。随后在该环境内部创建的匿名函数其[[Environment]]就指向这个环境。当(2)调用匿名函数时函数体内查找b会在自己的词法环境中命中值为2查找a时内部没有于是顺着外部引用找到sum(1)的词法环境命中a 1。这就是从外部词法环境获得a的完整链路。从闭包的定义来看闭包是指一个函数可以记住其外部变量并可以访问这些变量。在 JavaScript 中所有函数都是天生闭包的——函数会自动通过隐藏的[[Environment]]属性记住创建它们的位置因此它们都能访问外部变量。本题正是这一特性的最小化演示。与makeCounter的对比仓库中同章节的Counter 独立性问题使用了几乎相同的机制function makeCounter() { let count 0; return function() { return count; }; }makeCounter返回的函数同样通过闭包捕获了外层count变量每次调用makeCounter()都会创建一个全新的词法环境因此counter与counter2各自持有独立的count互不干扰输出为0,1,0,1而非0,1,2,3。与本题对比可以看出同一种模式的两种形态sum(a)的闭包捕获的是函数参数a只读使用makeCounter()的闭包捕获的是局部变量count跨多次调用持续读写。两者都印证了主教程中的结论在变量所在的词法环境中更新/读取变量以及不论在哪里调用函数仍然可以访问创建它时的外部变量。运行与验证原仓库的解答使用了浏览器环境下的alert输出结果你可以直接在浏览器控制台或任意支持 JavaScript 的运行环境中执行function sum(a) { return function(b) { return a b; }; } console.log(sum(1)(2)); // 3 console.log(sum(5)(-1)); // 4自测要点sum(1)的返回值类型必须是function可用typeof sum(1) function验证返回值函数仍能访问参数a证明闭包捕获生效双括号调用与普通两次调用等价sum(a)(b)恒等于先let f sum(a); f(b)。常见的错误写法直接相加后返回数值return a b——这样sum(1)得到3的数值无法再被(2)调用会抛出TypeError: ... is not a function用箭头函数同样可行const sum a b a b;原理完全相同只是语法更简洁。延伸思考通向柯里化返回函数的函数这一模式是函数式编程中**柯里化Currying**与部分应用的基础形态。sum(a)(b)其实就是把接收两个参数的函数改写为接收第一个参数并返回接收第二个参数的函数。仓库同章节的使用闭包求和 sum(a)(b)(c)...姊妹题以及makeArmy 练习都建立在同一套词法环境机制之上只要理解了每次调用创建独立词法环境 返回函数通过[[Environment]]捕获环境这两条规则就能正确预测闭包在各种嵌套场景下的行为。小结sum(a)(b)能工作的根本原因是sum(a)返回了一个函数函数是一等公民可以被返回并立即再次调用返回的内部函数通过闭包访问外层参数a其机制是词法环境链与隐藏属性[[Environment]]该练习是理解 JavaScript 闭包、柯里化风格的敲门砖同章节的makeCounter、sum系列练习可一并对照学习。如需继续深入可研读闭包主教程中关于词法环境、垃圾回收与 V8 引擎对未使用变量的优化调试时外部变量可能显示 No such variable等进阶内容。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐用闭包实现双括号求和JavaScript 教程 sum(a)(b) 任务全解用闭包实现双括号求和JavaScript 教程 sum a b 任务全解 导读 sum a b ab 是 en.javascript.infoMode文档/教程前端JavaScript 闭包实战用双括号 sum(a)(b) 实现函数求和JavaScript 闭包实战用双括号 sum a b 实现函数求和 导读 sum a b a b 是 JavaScript 教程中检验闭包 词文档/教程前端algorithm-pattern链表模板哑节点快慢指针一套模板秒杀6类链表高频面试题algorithm pattern链表模板哑节点快慢指针一套模板秒杀6类链表高频面试题 面试准备中最头疼的就是 链表题 去重、反转、合并、找中点、判断成文档教程前端上一篇网盘下载太慢怎么办8大平台直链解析工具LinkSwift深度评测下一篇LinkSwift9大网盘直链下载助手终极指南告别限速烦恼创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表