最近在看 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,面試的時候太愛問了~~