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
のみになります。私は何が間違っているのですか?
簡単な答え:this
は最も近い境界this
を指します-提供されたコードでは、this
は囲んでいるスコープにあります。
長い答え:矢印関数 作成時にthis
をバインドしますthis
、arguments
、またはその他の特別な名前がバインドされていませんまったく -オブジェクトが作成されているときに、名前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;
どちらの場合も、this
(shout関数の場合)は、person
オブジェクトに追加されたときに関数がアタッチされる新しいスコープではなく、person
が定義されているのと同じスコープを指します。
あなたcannot矢印関数をそのように機能させるが、@ kamituelが 彼の答え で指摘しているように、あなたcanを利用する同様のスペース節約を得るためのES6の短いメソッド宣言パターンの例:
var person = {
name: "Jason",
// ES6 "method" declaration - leave off the ":" and the "function"
shout() {
console.log("Hi, my name is", this.name);
}
};
@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"
受け入れられた答えは素晴らしく、簡潔で、明確ですが、ショーン・ビエイラが言ったことについて少し詳しく説明します。
矢印関数には、この引数やその他の特別な名前はまったくバインドされていません。
矢印関数には「this」がないため、親の「this」を使用します。 「this」は常に親を指し、personオブジェクトの親はWindowです(ブラウザを使用している場合)。
これをコンソールで実行することを証明するには:
var person = {
name: "Jason",
anotherKey: this
}
console.log(person.anotherKey)
Windowオブジェクトを取得します。
私はこれがそれについて考えるのに本当に役立つ方法だと思います。オブジェクトリテラルの「これ」が何であるかは別の議論であるため、それは完全な話ではありません。
ここで、関数内のこの値は、矢印関数が使用される場所ではなく、定義される場所によって決定されます。
したがって、this
は、他の名前空間にラップされていない場合、グローバル/ウィンドウオブジェクトを参照します
問題は、( [〜#〜] mdn [〜#〜] )
矢印関数式[...]は、この値を字句的にバインドします。
矢印関数は、囲んでいるコンテキストのこの値をキャプチャします。
したがって、その関数のthis
の値は、オブジェクトリテラルを作成するthis
の値になります。おそらく、それは非厳密モードではwindow
になり、厳密モードではundefined
になります。
これを修正するには、通常の機能を使用する必要があります。
var person = {
name: "jason",
shout: function(){ console.log("my name is ", this.name) }
}
person.shout();