javascript forEach 函数调用的调用上下文(this)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19707969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 16:33:36  来源:igfitidea点击:

The invocation context (this) of the forEach function call

javascriptfunctionforeachthisinvocation

提问by kevinius

I was wondering what the 'this' value (or invocation context) is of the forEach callback function. This code doesn't seem to work:

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

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

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

    this[i] = v + 1;

});

alert(jow);

Thx for explaining it to me.

感谢向我解释它。

采纳答案by kevinius

I finished construction of the forEach method and wanted to share this diagram with everyone, hope it helps someone else trying to understand its inner workings.

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

The forEach method

forEach 方法

回答by Tibos

MDN states:

MDN 声明:

array.forEach(callback[, thisArg])

If a thisArg parameter is provided to forEach, it will be used as the this value for each callback invocation as if callback.call(thisArg, element, index, array) was called. If thisArg is undefined or null, the this value within the function depends on whether the function is in strict mode or not (passed value if in strict mode, global object if in non-strict mode).

array.forEach(callback[, thisArg])

如果向 forEach 提供了 thisArg 参数,它将用作每个回调调用的 this 值,就像调用了 callback.call(thisArg, element, index, array) 一样。如果 thisArg 为 undefined 或 null,则函数内的 this 值取决于函数是否处于严格模式(如果是严格模式,则传递值,如果是非严格模式,则为全局对象)。

So in short, if you only provide the callback and you're in non-strict mode (the case you presented), it will be the global object (window).

所以简而言之,如果您只提供回调并且您处于非严格模式(您呈现的情况),它将是全局对象(窗口)。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

回答by vladvlad

Inside forEach, thisrefers to the global windowobject. This is the case even if you call it from a different object (i.e. one you've created)

里面的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

回答by thefourtheye

If you dont pass second parameter to forEach, thiswill point to the global object. To achieve what you were trying to do

如果不将第二个参数传递给forEach,this将指向全局对象。为了实现你想要做的

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

jow.forEach(function(v, i, a) {
    a[i] = v + 1;
});

console.log(jow);

Output

输出

[ 6, 11, 46, 68 ]

回答by benchuk

I have a very simple approach for the 'this' context question and it goes like this: whenever you want to know what is the context of 'this', check who is left to the caller if there is no caller to the left than it is the global else it is that object instance:

对于“this”上下文问题,我有一个非常简单的方法,它是这样的:每当您想知道“this”的上下文是什么时,如果左侧没有呼叫者,请检查呼叫者剩下的是谁是全局的,否则就是对象实例:

Examples:

例子:

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)

So, for the 'foreach' case when you give a callback function what actually happens in foreach implementation is something like that:

因此,对于“foreach”情况,当您提供回调函数时,foreach 实现中实际发生的情况类似于:

--> you call [1,2,3].foreach(callback,'optional This')

--> 你调用 [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])
  }
 }

Unless - you give it the optional 'this' or you bind the callback with a this (for example arrow function) if that happens than the called callback already has a 'this' obj which kind of 'blocks' you from changing it's given context more on bind can be found here enter link description hereBut basically the bind implementation look as follows:

除非 - 你给它可选的 'this' 或者你用 this 绑定回调(例如箭头函数),如果发生这种情况,那么被调用的回调已经有一个 'this' obj 那种'阻止'你改变它给定的上下文可以在此处找到有关绑定的更多信息 在此处输入链接描述但基本上绑定实现如下所示:

Function.prototype.bind = function (scope) {
    var fn = this;
    return function () {
        return fn.apply(scope);
    };
}

So you can see the fn (your callback) will always be called with your 'this' (scope)

所以你可以看到 fn(你的回调)总是用你的“这个”(范围)调用

Hope it helps...

希望能帮助到你...