项目场景:

看一段代码:

function test(arr) {
    (arr || []).forEach(console.log)
    (arr || []).forEach(console.log)
}
test([1,2,3])

他的执行结果是什么?

问题描述:

我们手动执行一下来验证自己的猜想吧:

Uncaught TypeError: (arr || []).forEach(...) is not a function
    at test (<anonymous>:3:5)
    at <anonymous>:5:1

发现报错了,提示报错是forEach is not a function。

原因分析:

为什么会出现这个报错呢,函数为了防止他是一个非数组还或上了空数组避免报错,那为什么还会报这个错误呢?
我们理所当然的可以用console.dir打印一下(arr || []),甚至都能在他的原型链上还能找到forEach方法。

console.dir([1,2,3] || [])

其实报错里就有玄机,我们重新看看报错,他报错的是forEach(…) is not a function,而不是我们常见的forEach is not a function。
forEach()这种形式其实是指forEach做函数调用的返回值不是一个函数,而并非forEach本身。
这里报错的也并不是第一个forEach,而是第一个forEach的返回值,我们换个写法来理解:

function test(arr) {
    (arr || []).forEach(console.log)(arr || [])
    .forEach(console.log)
}
test([1,2,3])

(arr || []).forEach(console.log)作为一个函数来调用,参数是arr || [],我们知道forEach是没有返回值的,也就是undefind作为一个函数来调用,本质上报错信息就是undefind is not a function。

解决方案:

我们知道报错的原因,解决方案也呼之欲出了:

function test(arr) {
    (arr || []).forEach(console.log);
    (arr || []).forEach(console.log)
}
test([1,2,3])

那么现在你敲代码还是不爱写分号吗?(🐶

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐