33

私はES6を試していて、関数内にプロパティを含めたいと思っています

var person = {
  name: "jason",

  shout: () => console.log("my name is ", this.name)
}

person.shout() // Should print out my name is jason

ただし、このコードコンソールを実行すると、ログのみが記録されmy name isます。私は何を間違っていますか?

4

5 に答える 5

50

短い答え:this最も近い境界を指しthisます-提供されたコードthisでは、それを囲むスコープにあります。

より長い答え: アロー関数 には、または他の特別な名前がまったくバインドされていませんthisarguments。オブジェクトが作成されているとき、名前thisはオブジェクトではなく、囲んでいるスコープで見つかりpersonます。宣言を移動すると、これをより明確に確認できます。

var person = {
  name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);

そして、ES5 の矢印構文の漠然とした近似に変換すると、さらに明確になります。

var person = {
  name: "Jason"
};
var shout = function() {
  console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;

どちらの場合も、 (shout 関数の場合)は、関数がオブジェクトに追加されたときにアタッチされる新しいスコープではなく、定義されthisているのと同じスコープを指します。personperson

アロー関数をそのように機能させることはできませんが、@kamituel が彼の回答で指摘しているように、ES6 の短いメソッド宣言パターンを利用して、同様のスペースを節約できます

var person = {
  name: "Jason",
  // ES6 "method" declaration - leave off the ":" and the "function"
  shout() {
    console.log("Hi, my name is", this.name);
  }
};
于 2015-03-01T19:59:40.207 に答える
32

@Sean Vieiraに同意します-この場合this、グローバルオブジェクトにバインドされます(または、コメントで指摘されているように、より一般的には囲みスコープにバインドされます)。

より短い構文が必要な場合は、別のオプションがあります。強化されたオブジェクト リテラルは、プロパティ関数の短い構文をサポートします。thisあなたがそこに期待するようにバインドされます。参照shout3():

window.name = "global";

var person = {
    name: "jason",

    shout: function () {
        console.log("my name is ", this.name);
    },
    shout2: () => {
        console.log("my name is ", this.name);
    },
    // Shorter syntax
    shout3() {
        console.log("my name is ", this.name);
    }
};

person.shout();  // "jason"
person.shout2(); // "global"
person.shout3(); // "jason"
于 2015-03-01T20:04:40.283 に答える
2

ここで、関数内の this の値は、矢印関数が使用されている場所ではなく、定義されている場所によって決まります。

したがってthis、他の名前空間にラップされていない場合は、グローバル/ウィンドウ オブジェクトを参照します

于 2015-03-01T20:04:07.887 に答える
0

問題は ( MDN )

アロー関数式 [...] は、この値を字句的にバインドします。

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

したがって、その関数の の値は、オブジェクト リテラルを作成する場所thisの値になります。thisおそらく、window非厳密モードと厳密モードになりundefinedます。

それを修正するには、通常の関数を使用する必要があります。

var person = {
  name: "jason",
  shout: function(){ console.log("my name is ", this.name) }
}
person.shout();
于 2015-03-01T20:06:33.110 に答える