我想知道 forEach 回调函数的“this”值(或调用上下文)是什么。此代码似乎不起作用:
var jow = [5, 10, 45, 67];
jow.forEach(function(v, i, a){
this[i] = v + 1;
});
alert(jow);
感谢向我解释它。
我想知道 forEach 回调函数的“this”值(或调用上下文)是什么。此代码似乎不起作用:
var jow = [5, 10, 45, 67];
jow.forEach(function(v, i, a){
this[i] = v + 1;
});
alert(jow);
感谢向我解释它。
MDN 声明:
array.forEach(callback[, thisArg])
如果向 forEach 提供了 thisArg 参数,它将用作每个回调调用的 this 值,就像调用了 callback.call(thisArg, element, index, array) 一样。如果 thisArg 为 undefined 或 null,则函数内的 this 值取决于函数是否处于严格模式(如果是严格模式,则传递值,如果是非严格模式,则为全局对象)。
所以简而言之,如果您只提供回调并且您处于非严格模式(您呈现的情况),它将是全局对象(窗口)。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
我完成了 forEach 方法的构建,想和大家分享这个图,希望它可以帮助其他人试图理解它的内部工作原理。
如果不将第二个参数传递给forEach
,this
将指向全局对象。为了实现你想要做的
var jow = [5, 10, 45, 67];
jow.forEach(function(v, i, a) {
a[i] = v + 1;
});
console.log(jow);
输出
[ 6, 11, 46, 68 ]
里面的forEach,this
指的是全局window
对象。即使您从不同的对象(即您创建的对象)调用它也是如此
window.foo = 'window';
var MyObj = function(){
this.foo = 'object';
};
MyObj.prototype.itirate = function () {
var _this = this;
[''].forEach(function(val, index, arr){
console.log('this: ' + this.foo); // logs 'window'
console.log('_this: ' + _this.foo); // logs 'object'
});
};
var newObj = new MyObj();
newObj.itirate();
// this: window
// _this: object
对于“this”上下文问题,我有一个非常简单的方法,它是这样的:每当您想知道“this”的上下文是什么时,如果左侧没有呼叫者,请检查呼叫者剩下的是谁是全局的,否则就是对象实例:
例子:
let obj = { name:"test", fun:printName }
function printName(){
console.log(this.name)
}
//who is left to the caller? obj! so obj will be 'this'
obj.fun() //test
//who is left to the caller? global! so global will be 'this'
printName() //undefined (global has no name property)
因此,对于“foreach”情况,当您提供回调函数时,foreach 实现中实际发生的情况类似于:
--> 你调用 [1,2,3].foreach(callback,'optional This')
foreach(arr,cb)
{
for(i=0; i<arr.len;i++)
{
//who is left to the caller? global! so it will be 'this'
cb(arr[i])
}
}
除非 - 你给它可选的 'this' 或者你用 this 绑定回调(例如箭头函数),如果发生这种情况,那么被调用的回调已经有一个 'this' obj 那种'阻止'你改变它给定的上下文可以在此处找到有关绑定的更多信息 在此处输入链接描述 但基本上绑定实现如下所示:
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
return fn.apply(scope);
};
}
所以你可以看到 fn(你的回调)总是用你的“这个”(范围)调用
希望能帮助到你...