2016-01-09 3 views
8

誰かが私にレキシカルの簡単な紹介をしてくれますか?字句「this」とは何ですか?

「(また、脂肪の矢印機能として知られている)、矢印関数式は、関数式に比べて短い構文を持っており、辞書的にこの値をバインドし(この独自のを結合しない、スーパー引数、またはnew.target)矢印機能は常に匿名です。

「ファットアロー」関数から 'this' refを使用して関数メンバを呼び出すと、 'this'は常に 'this'を参照していますか?

+2

はい、矢印関数の 'this'は、矢印関数が作成されたコンテキストと同じ値を持ちます。 – Pointy

+0

は、そのリスナーでクリックリスナーを持っていて、setTimeoutのようないくつかのAjax操作を実行しているとします。コールバック内のコードが完了すると、クリックされたボタンの色を変更するためにコールバックが実行されます。コントロールはajax操作のためにコンテキストから外れるでしょう。あなたはthis.soにアクセスできません.es6は、問題を修正するために矢印関数を導入しました – sundar

+1

[この投稿は@getifyから](http://blog.getify.com/arrow- this)は、いわゆる「this」と呼ばれる主語の絶対読み込みである* – CodingIntrigue

答えて

5

あなたはクリックリスナーを持っていると言います。そのリスナーでは、setTimeoutのようないくつかのAJAX操作を実行しています。設定された時間に達すると、コールバック内のコードが実行されます。そのコールバックの中で、thisにアクセスして、クリックされたボタンの色を変更することができます。しかし、AJAX操作のために制御が文脈から外れることになります。 ES2015では、この問題を解決するための矢印機能が導入されました。矢印関数は、囲むコンテキストのthis値を取得します。

例使用の場合は、次のとおりです。

$('.btn').click(function() { 
    setTimeout(function() { 
     $(this).text('new'); 
     // This will cause an error since function() defines this as the global object. 
    } ,100); 
}); 

このケースを避けるために:

$('.btn').click(function() { // <- Enclosing context 
    setTimeout(() => { 
     $(this).text('new') } 
     // This works, because this will be set to a value captured from the enclosing context. 
     ,100); 
}); 
2

私はwrote an article about thisの要旨は以下のとおりです。はないは、どのような "字句この" についてどう思います手段。 ではなく、は、矢印機能内での「これ」の意味を心配しています。 はすでにを知っています(少なくとも、そうしないと、矢印機能の障害ではなく、一部の外部機能スコープについての混乱の欠点です)。

いくつかのネストされた、またはより高次の機能の中でそれを使用する必要があるときに、「これ」が何を意味するのか心配するために何年も調整されているかもしれません。しかし、矢印機能を使用するだけで、それを心配するのを止めることができます。あなたは現在、あなたが現在いる文脈の中で「これ」が何を指しているかをほぼ確実に知っています。矢印の機能の中では、変化していません。矢印関数を単純なケースと考え、function(){}を複雑なものとして考えてください。

いくつかの関数を書いてif(){}ブロックを開始し、 "this"がその内部に変更された可能性について心配していませんか?いいえ?矢印機能と同じです。それが「語彙的」とはどういう意味ですか。それは、「ハクナマタタ」を意味します。

+1

これは、過去20年間の「this」の動作と、すべてのJSコードの中心にある複雑な動作であると私は少し奇妙に思います。それについて何が複雑ですか?もしそれが複雑であれば、その矢印関数はすべて、自分自身の 'this 'を定義しないことによって、その複雑さを囲む関数スコープに渡します。 –

+0

あなたは、矢印関数がいつも望むように動作し、通常の関数が決して動作しないように説明します。しかし、通常の関数に対する 'this 'の振る舞いも有用です。プロトタイプでメソッドを定義するとき – Oriol

+0

矢印機能は "this"の現在の意味を変更しません。したがって、特別な、紛らわしい説明のない新しい精神モデルは、「彼らが何を意味するか」を理解するために必要です。それが何を指しているかは変わっていない。それでおしまい。そして、はい、通常の機能は客観的にもっと複雑です。彼らは心配するいくつかのより動的なプロパティを持っています。彼らが20年間暮らしてきたことは、その質問には関係していません。はい、彼らはまだ有用です。しかし、彼らはもはや仕事のための唯一のツールではありません。私はちょうど言っている:できるだけ簡単なものを使う。 – Dtipson

4

矢印機能のthisの動作を説明する方法として、「字句this」という用語は、混乱しているものと誤っているものとの間にあります。

矢印機能のthisは、周囲の機能のthisを参照しています。矢印機能が定義していない(またはバインドしていない)というだけで、 )this

「字句this」の残念な用語は、(最近までも時代遅れ用語「脂肪の矢印機能」を使用する人々を奨励する)MDN article on arrow functionsに文言のお粗末な選択によって永続された可能性があります。これは今清算されました。また、矢印関数のthisに関しては、この仕様では「字句」という用語を使用しないことにも注意してください。私は誰がこの表現を思いついたのか不思議に思います。

8

あなたは矢印の機能にthisで何が起こるかを正確に理解しているように見えます。私は、会話に追加すると思う説明を提供し、うまくいけばあなたの理解を固めます。変数はその範囲で定義されている場合

あなたが関数を定義し、その中に変数を使用するときには、おそらく、知っているように、それがチェックされます。そうであれば、それを使用します!そうでなければ、変数定義の囲みスコープをチェックします。変数が見つかるか、グローバルスコープに達するまで、囲みスコープのチェックを続けます。今、ではなくの関数定義は暗黙的にthisを定義しています。したがって、スコープ内にthisを使用しようとすると、囲みスコープをチェックすることはありません(自分のスコープ内にあるため)。アロー機能はthis、独自に定義していないので、彼らが囲むスコープに行くと、彼らは任意の変数を使用すると、その範囲で使用しようとするのと同じように、それを探してください。 ES6脂肪矢印機能でこれを使用して

+0

これは間違っています。変数は、スコープチェーン全体に沿って検索されます。 'this'は正確**すぐに**囲む範囲で、矢印の機能の場合は、「い」されます。 –

+1

私はそれに同意しないか分からない。おそらく私は不明だったでしょう。あなたの最後の文について:ネストされた矢印関数はどうですか? – jakeehoffmann

-1

、これがに参照されているものをチェックし続け、通常のES5関数宣言とは異なり、これはこれは、特定の範囲は、それに割り当てられている中で何を参照するかという意味でレキシカルスコープを持つようになりますそれが見つかるまで、最も内側のスコープからグローバルなスコープへと始まります。

function foo() { 
setTimeout(() => { 
    // `this` here is lexically adopted from `foo()` 
    console.log(this.a); 
},100); 
} 
var obj = { 
    a:2 
}; 
foo.call(obj); //2 

一方、プリES6、程度の範囲

function foo() { 
var self = this; // lexical capture of `this` 
setTimeout(function(){ 
    console.log(self.a); 
}, 100); 
} 
var obj = { 
    a: 2; 
}; 
foo.call(obj); //2 
0
このローカル変数を作る、このキーワードを割り当てることによって、JavaScriptでレキシカルスコープを実装する方法がありました

これは、 'Fat Arrow'関数からの 'this' refを使用して関数メンバーを呼び出すと、 'this'は常に 'this'を囲むことを意味しますか?

質問に対する回答はありです。すでに述べたように、彼らは順番に、私たちに脂肪矢印関数内thisの呼び出しが応答する方法を制御する機会を与え囲んでいるコンテキストの参照を使用するように、脂肪の矢印機能がthisの参照を持っていません。例えばのために

thisの使用は、外側のコンテキストを探します可能オブジェクト内の脂肪矢印機能を有します。この場合、コンテキストは、window次のとおりです。

var foo = { 
    bar:() => this.baz // 'this' is window  
} 

ただし、パブリッククラスフィールドの構文あるES6の構文を使用している場合:

class MyClass { 
    handleEvent =() => { 
    this.letsCode(); // 'this' is instance of MyClass 
    } 
} 

renderに使用してのような他の多くのインスタンスが(あります太い矢印の機能が使用されているこの質問の範囲外であり、thisが使用されているコンテキストに適切にバインドされているので、その性質を制御する機能を提供します。それが役に立てば幸い!

関連する問題