<h4>bindそのものについて</h4> <p>JSのbindの用法を知り、「どういう時に使われるのか」が漠然とイメージできるようになりたかったため、概要と使われ方を調べた。</p> <p>とりあえず以下のサイトのデモコードを自分なりにいじってどういう挙動なのかは調べた。</p> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind() - JavaScript | MDN</a></p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synStatement">const</span> module = <span class="synIdentifier">{</span> a: 50, b: 30, text: <span class="synConstant">'this is test'</span>, showText: <span class="synIdentifier">function</span>()<span class="synIdentifier">{</span> <span class="synStatement">return</span> <span class="synIdentifier">this</span>.text; <span class="synIdentifier">}</span>, <span class="synIdentifier">}</span>; <span class="synStatement">const</span> moduleShow = module.showText; console.log(moduleShow); <span class="synComment">// moduleから抜き出した関数にmodule自体をbindする</span> <span class="synComment">// moduleShow内のthis = bindされたmoduleとなる</span> <span class="synComment">// そのため、this.text = module.text、になる</span> <span class="synStatement">const</span> boundGetX = moduleShow.bind(module); console.log(boundGetX()); </pre> <p><br></p> <p>その他、bindの概要、callとの違いについては下記の記事を見てイメージは出来た。 <a href="https://itsakura.com/js-bind">JavaScript this&#x306E;&#x5185;&#x5BB9;&#x3092;&#x6307;&#x5B9A;&#x3059;&#x308B;(bind&#x30E1;&#x30BD;&#x30C3;&#x30C9;) | ITSakura</a></p> <p>ただ、こいつがどういう目的で使われるかは分からなかった。<a href="#f-81413229" name="fn-81413229" title="こういったサンプルを見て、「じゃあこういうものにも応用できるな」と考えつく能力もプログラマに必要不可欠な能力だよな、と最近感じている">*1</a></p> <p>単純に、関数内のthis(thisがない場合はbind内の第一引数にnullを指定する)を特定のものに設定する(=undefinedにしない)場合にbindを使う、という使い方でいいのだろうか。</p> <h4>アロー関数内でのthisの扱われ方とbindの比較</h4> <p>ここまで調べて、そういえばJSの通常関数とアロー関数ではthisの指すものが異なる、という話しを思い出した。</p> <p><a href="https://qiita.com/mejileben/items/69e5facdb60781927929">&#x3010;JavaScript&#x3011;&#x30A2;&#x30ED;&#x30FC;&#x95A2;&#x6570;&#x5F0F;&#x3092;&#x5B66;&#x3076;&#x3064;&#x3044;&#x3067;&#x306B;this&#x3082;&#x5FA9;&#x7FD2;&#x3059;&#x308B;&#x8A71; - Qiita</a></p> <p><a href="https://qiita.com/suin/items/a44825d253d023e31e4d">JavaScript: &#x901A;&#x5E38;&#x306E;&#x95A2;&#x6570;&#x3068;&#x30A2;&#x30ED;&#x30FC;&#x95A2;&#x6570;&#x306E;&#x9055;&#x3044;&#x306F;&#x300C;&#x66F8;&#x304D;&#x65B9;&#x3060;&#x3051;&#x300D;&#x3067;&#x306F;&#x306A;&#x3044;&#x3002;&#x7570;&#x306A;&#x308B;&#x6027;&#x8CEA;&#x304C;10&#x500B;&#x307B;&#x3069;&#x3042;&#x308B;&#x3002; - Qiita</a></p> <p><br></p> <p>両者の<code>this</code>に関する違いとしては、アロー関数は<code>this</code>を束縛し、通常関数は<code>this</code>を束縛しない(=関数呼び出し元(レシーバ)をthisとする)という点である。</p> <p>下記のコードを例に比較する。</p> <ul> <li>通常関数</li> </ul> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">this</span>.name = <span class="synConstant">&quot;globalName&quot;</span>; <span class="synComment">// 通常関数</span> <span class="synIdentifier">function</span> showName() <span class="synIdentifier">{</span> console.log(<span class="synIdentifier">this</span>.name); <span class="synIdentifier">}</span> <span class="synIdentifier">let</span> arrowFunc = <span class="synIdentifier">{</span> name: <span class="synConstant">&quot;john&quot;</span>, func: showName, <span class="synIdentifier">}</span>; arrowFunc.func(); =&gt; john <span class="synComment">// bindを使った場合</span> showName.bind(arrowFunc)(); =&gt; john </pre> <p><code>arrowFunc.func()</code>の返り値が<code>john</code>となっており、これはarrowFunc.nameの値であることが分かる。 このことから、<code>arrowFunc.func()</code>、つまりは<code>arrowFunc.showName()</code>のshowName内部のthisはarrowFunc(レシーバ)を指していたことが分かる。 <br></p> <ul> <li>アロー関数</li> </ul> <pre class="code lang-javascript" data-lang="javascript" data-unlink> <span class="synIdentifier">this</span>.name = <span class="synConstant">&quot;globalName&quot;</span>; <span class="synComment">// アロー関数</span> <span class="synStatement">const</span> showName = () =&gt; <span class="synIdentifier">{</span> console.log(<span class="synIdentifier">this</span>.name); <span class="synIdentifier">}</span>; <span class="synIdentifier">let</span> arrowFunc = <span class="synIdentifier">{</span> name: <span class="synConstant">&quot;john&quot;</span>, func: showName, <span class="synIdentifier">}</span>; arrowFunc.func(); =&gt; globalName </pre> <p><code>arrowFunc.func()</code>の返り値が「globalName」となっている。これは最初に定義した<code>this.name = "globalName"</code>のnameの値が表示されていることが分かる。 ここで、アロー関数内のthisについてのリファレンスを見てみる。</p> <blockquote><p>アロー関数自身は this を持ちません。レキシカルスコープの this 値を使います。つまり、アロー関数内の this 値は通常の変数検索ルールに従います。このためスコープに this 値がない場合、その一つ外側のスコープで this 値を探します。</p></blockquote> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this">&#x30A2;&#x30ED;&#x30FC;&#x95A2;&#x6570; - JavaScript | MDN</a></p> <p><br></p> <p>アロー関数である<code>showName</code>が定義された際、関数内のthisは更に外側のthisを見ていたことになる。 今回Node上で上記コードを実行したため、thisとして定義されていたのは<code>{name: "globalName"}</code>だったため、<code>showName</code>関数内のconsole.logで表示されたthis.nameは、コードの最初に定義したthis.nameだった、ということになる。</p> <p><br></p> <p>ちなみにトッ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D9">プレベ</a>ル、グロー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%EB%A5%B9">バルス</a>コープあたりはここを参考にした。</p> <p><a href="https://qiita.com/qeema/items/0b7e2ff4e33703a42a40">JavaScript&#x306E;&#x30C8;&#x30C3;&#x30D7;&#x30EC;&#x30D9;&#x30EB;&#x30B9;&#x30B3;&#x30FC;&#x30D7;&#x306F;&#x5E38;&#x306B;&#x30B0;&#x30ED;&#x30FC;&#x30D0;&#x30EB;&#x30B9;&#x30B3;&#x30FC;&#x30D7;&#x3067;&#x306F;&#x306A;&#x304B;&#x3063;&#x305F; - Qiita</a></p> <h4>まとめ</h4> <p>改めて<code>bind</code>、通常関数とアロー関数それぞれでのthisの使い方を確認した。 通常関数とアロー関数の違いについては他にも色々あるが、一旦知りたいと思っていたことを確認することができた。</p> <div class="footnote"> <p class="footnote"><a href="#fn-81413229" name="f-81413229" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">こういったサンプルを見て、「じゃあこういうものにも応用できるな」と考えつく能力も<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>に必要不可欠な能力だよな、と最近感じている</span></p> </div>