题目描述
代码中使用了 fn.call(null) 写法,这里直接使用 fn() 是否合理?或者说哪些情况时将会不符合预期。
题目来源及自己的思路
axios 的 utils 源码关于 forEach 的实现
我的理解 fn.call(null) 此时 this 会指向 window(浏览器环境),但是这里直接使用 fn() 是否可以
相关代码
function forEach(obj, fn) {
// Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') {
return;
}
// Force an array if not already something iterable
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj];
}
if (isArray(obj)) {
// Iterate over array values
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
// Iterate over object keys
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
}
}
你期待的结果是什么?实际看到的错误信息又是什么?
很多时候不太理解 call 的实战使用场景
这是做了兼容性处理,所以不能用fn()替代的。
在调用forEach的时候,fn可能是一个纯函数,也可能是一个实例的方法,所以call(null)的作用是防止fn中使用了this,且this指向了原始实例引起的错误。
这个代码很怪,但是不重要,因为写函数(forEach)的人是不能确定调用者会传入的fn是什么样子的。而且,如果fn中对this强依赖直接报错,也是目的之一。
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。