关于TypeScript map调用带默认参数HOF的运行机制咨询
问题成因详解
核心原因:Array.prototype.map 固定给回调传入3个参数
JS 中所有数组实例的 map 方法,对传入的回调函数有固定的传参规则,每轮遍历都会按顺序给回调传入3个值:
- 第一个参数:当前遍历到的数组元素值
- 第二个参数:当前元素在数组中的索引(从0开始计数)
- 第三个参数:调用
map方法的原数组
不管你定义的回调函数声明了几个形参,这三个值都会按顺序完整传入。
对你提供的示例的逐行解释
单元素数组场景
你的代码如下:
function add(a: number, b: number = 1) { console.log(b) // 0 return a + b } console.log([1].map(add)) // [1]
当 [1].map(add) 执行时:
- 数组只有1个元素,只会触发1次
add调用 - 按
map的传参规则,传入add的实参是(1, 0, [1]) - 你的
add函数第二个形参b虽然设置了默认值1,但默认参数仅在对应位置没有传参、或传入的是undefined时才会生效,这里明确传入了第二个实参0,所以b的取值是0而非1 - 最终计算结果为1+0=1,输出数组
[1],和你看到的结果完全一致。
多元素数组场景
你的代码如下:
function add(a: number, b: number = 1) { console.log(b) // 1,2 return a+b } console.log([1,2,3].map(add)) // [1, 3, 5]
这里需要说明一个注释小笔误:实际console.log(b)会依次输出0,1,2,你漏了第一次调用输出的0:
- 数组有3个元素,触发3次
add调用,传入的实参分别是:- 第一次:
(1, 0, [1,2,3])→ b=0 → 1+0=1 - 第二次:
(2, 1, [1,2,3])→ b=1 → 2+1=3 - 第三次:
(3, 2, [1,2,3])→ b=2 → 3+2=5
- 第一次:
- 最终输出数组
[1,3,5],和你的运行结果一致。
如果你想让默认参数生效的写法
如果你希望add的第二个参数b使用默认值1,不要接收map传入的索引,只需要给map传一层匿名函数包裹,只把第一个元素传给add即可:
// 此时add只收到第一个参数,第二个参数无传参,默认使用1 console.log([1,2,3].map(item => add(item))) // 输出 [2,3,4]
内容的提问来源于stack exchange,提问作者Toan Nguyen
相关产品推荐
相关产品推荐

