34

我想知道 forEach 回调函数的“this”值(或调用上下文)是什么。此代码似乎不起作用:

var jow = [5, 10, 45, 67];

jow.forEach(function(v, i, a){

    this[i] = v + 1;

});

alert(jow);

谢谢你向我解释。

4

5 回答 5

52

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

于 2013-10-31T13:37:32.607 回答
10

我完成了 forEach 方法的构建,并想与大家分享这张图,希望它能帮助其他人试图理解它的内部工作原理。

forEach 方法

于 2013-10-31T14:33:44.337 回答
6

如果您不将第二个参数传递给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 ]
于 2013-10-31T13:39:35.827 回答
6

在 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
于 2016-07-15T16:34:49.807 回答
1

对于“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 (你的回调)总是用你的 'this' (范围)调用

希望能帮助到你...

于 2019-02-20T08:03:18.190 回答