web-dev-qa-db-ja.com

forEach関数呼び出しの呼び出しコンテキスト(this)

私は、「this」値(または呼び出しコンテキスト)がforEachコールバック関数のものであると思っていました。このコードは機能していないようです:

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

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

    this[i] = v + 1;

});

alert(jow);

私にそれを説明するためのTHX。

25
kevinius

ForEachメソッドの構築を終了し、この図をすべての人と共有したいと考えました。他の誰かがその内部の仕組みを理解するのに役立つことを願っています。

The forEach method

10
kevinius

MDNの状態:

array.forEach(callback [、thisArg])

ThisErgパラメータがforEachに提供される場合、callback.call(thisArg、element、index、array)が呼び出されたように、各コールバック呼び出しのthis値として使用されます。 thisArgが未定義またはnullの場合、関数内のthis値は、関数がストリクトモードかどうかによって決まります(ストリクトモードの場合は渡された値、非ストリクトモードの場合はグローバルオブジェクト)。

つまり、コールバックのみを提供し、非厳密モード(提示した場合)にある場合、それはグローバルオブジェクト(ウィンドウ)になります。

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

44
Tibos

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
4
vladvlad

2番目のパラメーターを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 ]
3
thefourtheye

「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'オブジェクトを持っている場合は、コンテキストの変更をブロックしますバインドの詳細はこちら にリンクの説明を入力してください しかし、基本的にバインドの実装は次のようになります。

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

したがって、fn(コールバック)が常に 'this'(スコープ)で呼び出されることがわかります。

それが役に立てば幸い...

0
benchuk