最近在看 axios
的源码,里面有一些简写,好比:node
utils.forEach(fns, function transform(fn) { data = fn(data, headers); });
好奇心驱使我又去看了下 forEach
的封装,以下:ios
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
,那它有什么用呢?试着在控制台执行如下代码:git
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
。github
结论:call/apply
的第一个参数为 null
时,this
是 js 执行环境的全局变量,浏览器中是 window
,其余环境(如node
)是 global
。面试
另 axios
的 utils
中封装的各类数据类型的判断好全啊哈哈哈,附上地址:https://github.com/axios/axios/blob/master/lib/utils.js,面试的时候太爱问了~~axios