MDN中call()调用匿名函数示例的i形参是否为可省略的重复参数?
关于示例中形参i是否可省略的解答
你观察到的结论是正确的,代码第7行的形参i属于可选参数,确实可以直接省略,修改后的运行结果和原代码完全一致。
原理说明
Function.prototype.call()的参数规则是:第一个参数为被调用函数的this绑定对象,从第二个参数开始的所有入参,都会按顺序作为实参传递给目标函数。- 原代码中形参
i的作用,是接收call()传入的第二个参数,在匿名函数内部创建当前循环轮次i值的独立副本,避免外部变量变化影响内部取值。 - 你省略形参后结果不变,是因为示例的for循环使用
let声明循环变量i:ES6中let声明的循环变量具备块级作用域,每一轮循环的i都是独立的绑定变量,匿名函数就算不接收形参i,内部访问到的i就是当前轮次的块级作用域变量,取值完全一致。
两种写法的差异场景
如果把示例中for循环的let i替换为var i,两种写法就会出现明显区别:
- 保留形参
i的写法:依然可以正常输出#0、#1的序号,因为形参已经捕获了当前轮次的i值 - 省略形参
i的写法:如果内部存在异步逻辑(比如把打印逻辑放到setTimeout中),最终输出的序号都会是2,因为var声明的i没有块级作用域,循环结束后i的值会变为2,异步执行时读取的就是最终的i值
原示例保留形参的意义
MDN的示例中保留这个形参,是更通用的兼容写法:在ES6正式推出let关键字之前,开发者普遍通过这种「形参接收传值」的方式来捕获循环轮次的变量值,规避变量提升带来的作用域问题。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

