web-dev-qa-db-ja.com

ES6の矢印関数で「これ」とは何を指しますか?

主な違いは、「thisは矢印関数で字句的にバインドされている」ということです。それはすべて順調ですが、実際にはそれが何を意味するのかわかりません。

私はそれが関数の本体を定義する中括弧の範囲内で一意であることを知っていますが、太い矢印を参照していない限り、thisが何を参照しているかわからないので、実際に次のコードの出力を伝えることができませんでした関数自体....これは有用ではないようです。

var testFunction = () => { console.log(this) };
testFunction();
45

矢印関数は、囲んでいるコンテキストのthis値をキャプチャします

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

したがって、質問に直接答えるために、矢印関数内のthisは、矢印関数が割り当てられる直前と同じ値になります。

35
dave

全体像を提供するために、動的バインディングと字句バインディングの両方について説明します。

ダイナミックネームバインディング

thisは、メソッドが呼び出されるオブジェクトを参照します。これは、SOで定期的に読まれる文です。しかし、それはまだフレーズであり、かなり抽象的なものです。この文に対応するコードパターンはありますか?

はいあります:

_const o = {
  m() { console.log(this) }
}

// the important patterns: applying methods

o.m(); // logs o
o["m"](); // logs o
_

mthisに依存しているため、メソッドです。 o.m()またはo["m"]()は、moに適用されることを意味します。これらのパターンは、有名なフレーズへのJavascriptの翻訳です。

次のことに注意する必要がある別の重要なコードパターンがあります。

_"use strict";

const o = {
  m() { console.log(this) }
}

// m is passed to f as a callback
function f(m) { m() }

// another important pattern: passing methods

f(o.m); // logs undefined
f(o["m"]); // logs undefined
_

前のパターンと非常によく似ており、括弧のみが欠落しています。しかし、結果はかなりのものです。mを関数fに渡すと、そのオブジェクト/コンテキストmのout oを引き出します。現在はルート化されており、thisは何も参照していません(厳密モードが想定されます)。

字句(または静的)名前バインディング

矢印関数には、独自のthis/super/argumentsバインディングがありません。親のレキシカルスコープからそれらを継承します。

_const toString = Object.prototype.toString;

const o = {
  foo: () => console.log("window", toString.call(this)),
      
  bar() {
    const baz = () => console.log("o", toString.call(this));
    baz();
  }
}

o.foo() // logs window [object Window]
o.bar() // logs o [object Object]_

グローバルスコープ(ブラウザのWindow)以外に、関数のみがJavascript(およびES2015の_{}_ブロック)でスコープを形成できます。 _o.foo_矢印関数が呼び出されると、bazthisを継承できる周囲の関数はありません。したがって、thisオブジェクトにバインドされているグローバルスコープのWindowバインディングをキャプチャします。

bazが_o.bar_によって呼び出されると、矢印関数は_o.bar_で囲まれ(_o.bar_は親レキシカルスコープを形成します)、_o.bar_のthisバインディング。 _o.bar_はoで呼び出されたため、そのthisoにバインドされます。

16
user6445533

このコードショーで、より明確なアイデアが得られることを願っています。基本的に、矢印関数の「this」は「this」の現在のコンテキストバージョンです。コードを参照してください:

// 'this' in normal function & arrow function
var this1 = {
    number: 123,
    logFunction: function () { console.log(this); },
    logArrow: () => console.log(this)
};
this1.logFunction(); // Object { number: 123}
this1.logArrow(); // Window 
3
Xin

矢印関数thisはEs6の周囲の親を指しています。これは、ES5の匿名関数のようにスコープしないことを意味します...

これは、ES5で広く使用されているvar selfをこれに割り当てることを避けるための非常に便利な方法です...

次の例を見て、オブジェクト内に関数を割り当てます。

var checkThis = {
  normalFunction: function () { console.log(this); },
  arrowFunction: () => console.log(this)
};

checkThis.normalFunction(); //Object {}
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}
2
Alireza

以下の方法で理解することができます

// whatever here it is, function or fat arrow or literally object declare
// in short, a pair of curly braces should be appeared here, eg:
function f() {
  // the 'this' here is the 'this' in fat arrow function below, they are
  // bind together right here
  // if 'this' is meaningful here, eg. this === awesomeObject is true
  console.log(this) // [object awesomeObject]
  let a = (...param) => {
    // 'this is meaningful here too.
    console.log(this) // [object awesomeObject]
}

したがって、太い矢印関数の「this」はバインドされていません。つまり、ここで「this」にバインドすることはできません。applyはできません。 太い矢印関数の「this」は、テキストエディタでコードテキストを書き留めるときにバインドされます。ここでは、太い矢印関数の「this」は文字通り意味があります。ここでテキストエディターでコードを記述すると、アプリがreplでそこで実行されます。 テキストエディターで変更しない限り、ファットアラーでバインドされた「this」は変更されません。私のプール英語でごめんなさい...

1
Plasmatium

矢印関数はthisキーワードとバインドしません

var env = "globalOutside";
var checkThis = {env: "insideNewObject", arrowFunc: () => {
console.log("environment: ", this.env);
} }

checkThis.arrowFunc()   // expected answer is environment: globalOutside

// Now General function 
var env = "globalOutside";
var checkThis = {env: "insideNewObject", generalFunc: function() {
console.log("environment: ", this.env);
} }
checkThis.generalFunc() // expected answer is enviroment: insideNewObject

// Hence proving that arrow function never binds with 'this'
0
TrickOrTreat

別の例では、下の年齢ボタンをクリックすると

<script>
var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: function() {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

var person2 = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: () => {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

</script>



<input type=button onClick="alert(person2.age());" value="Age">

このような例外をスローします

×JavaScriptエラー:Uncaught TypeError:18行目のundefinedのプロパティ 'getFullYear'を読み取れません

しかし、person2のこの行を変更すると

return new Date().getFullYear() - this.dob.getFullYear(); 

return new Date().getFullYear() - person2.dob.getFullYear();

person2でこのスコープが変更されたため、機能します

0
Hamit YILDIRIM