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

IT技术 javascript function foreach this invocation
2021-02-04 21:03:07

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

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

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

    this[i] = v + 1;

});

alert(jow);

感谢向我解释它。

5个回答

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

您将数组中的值用作要更改的元素的索引。第一次迭代将 jow[1] 更改为 5(将 2 替换为 5),第二次将 jow[5] 更改为 5(在最后添加另一个 5),第三次将 jow[3] 更改为 5(将 4 替换为 5),每隔一个迭代将 jow[5] 更改为 5。
2021-03-18 21:03:07
真奇怪。如果我在一个对象上创建一个方法,那么“this”值将是那个对象。为什么这是不同的?
2021-03-22 21:03:07
谢谢,我到了那里......我使用 jow 数组作为 thisArg,但我得到了不好的结果:jsfiddle.net/39LSg这是为什么?-this- 的值似乎随着 window 对象和 jow 数组之间的每次迭代而跳跃
2021-03-22 21:03:07
MDN 说,然而,在严格模式下,this的值保持在进入执行上下文时设置的任何在类方法的上下文中,作为 forEach 的参数传递的嵌套经典函数将保留原始类实例作为 t​​his 值(假设该函数不是强制的),听起来像箭头函数的行为不是吗!?
2021-03-27 21:03:07
thisforEach 的主体内部确实是您的特定数组,但它与您提供的回调之间没有联系。回调被调用,但是 forEach 的实现需要,特别是 thisArg、window 或 element 作为 this。
2021-03-31 21:03:07

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

forEach 方法

forEach()上下文应该在这个上下文内。在 sdev 中,上下文几乎总是包装它的孩子。我喜欢 UML 风格的方法。
2021-03-14 21:03:07
大声笑这个图中的间距实际上并不意味着什么
2021-03-28 21:03:07
我的意思是一般的布局,这个图是完全不可读的
2021-03-29 21:03:07

如果不将第二个参数传递给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
这大多是真的。但是您可以thisArg在回调之后传递 a来定义this引用的内容。在你的例子中,你可以调用[''].forEach(function (…) {…}, myObj),这样它this.foo就会返回'object'而不是'window'
2021-03-26 21:03:07
有趣的是,默认情况下, thethisArg指的是全局window对象(我已经在我的浏览器中测试过),而在规范中它说如果没有thisArg提供,则undefined默认情况下应该是MDN:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...规范:ecma-international.org/ecma-262/5.1/#sec-15.4.4.18
2021-04-11 21:03:07

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

希望能帮助到你...