最近在看 axios
的源码,里面有一些简写,比如:
utils.forEach(fns, function transform(fn) {
data = fn(data, headers);
});
好奇心驱使我又去看了下 forEach
的封装,如下:
function forEach(obj, fn) {
// 循环变量为空时,直接return
if (obj === null || typeof obj === 'undefined') {
return;
}
// 如果 obj 不可遍历,则强制转为数组
if (typeof obj !== 'object') {
obj = [obj];
}
if (isArray(obj)) {
// 遍历数组
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
// 遍历对象
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
}
}
仔细看,遍历里面其实就是执行从外面传入的 fn
,不必要使用 call
函数,而且第一个参数传的是 null
,那它有什么用呢?试着在控制台执行以下代码:
function forEach(obj, fn) {
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
}
var text = '示例文字';
forEach(['a','b','c'],function({console.log(this.text)})
嗯能看到 call
第一个参数传 null
时,this
指向了 window
。
结论:call/apply
的第一个参数为 null
时,this
是 js 执行环境的全局变量,浏览器中是 window
,其他环境(如node
)是 global
。
另 axios
的 utils
中封装的各种数据类型的判断好全啊哈哈哈,附上地址:https://github.com/axios/axios/blob/master/lib/utils.js,面试的时候太爱问了~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。