19
15

More than 3 years have passed since last update.

TypeScriptでFunction.bindを使うのはよくない

Last updated at Posted at 2018-10-02

追記

TypeScript 3.2 RC にてBind周りに変更が入りました

詳細については以下の記事を参考にしてください!
https://qiita.com/vvakame/items/79557e00cfe6d3c612cd

はじめに

みなさんご存知かと思いますが、
JavaScriptのthisは他の言語では考えられない動きをします。
そこでthisを固定するために.bind関数を使うことが一般的ですが、
TypeScriptの場合はそうはいきません。

何故なのか

まずはbindがどういう定義になっているのか見てみましょう

 Function.bind(this: Function, thisArg: any, ...argArray: any[]): any

はい。
色々とanyです。

せっかくの型を大事にする言語なのにこれでは台無しです。

じゃあどうすれば?

マイクロソフト公式がthisの扱いについてページを作っているので
ここを元に解説していきます。公式

Use Instance Functions

TypeScriptのクラスとしてデフォルトのプロトタイプメソッドではなく、
インスタンスにアロー関数を生やす形で定義します。

class MyClass {
    private status = "blah";

    public run = () => { // <-- note syntax here
        alert(this.status);
    }
}
var x = new MyClass();
$(document).ready(x.run); // SAFE, 'run' will always have correct 'this'

いい点

  • 使用する人がthisついて処理漏れが起きません
  • 型安全です
  • 関数にパラメータがある場合は、追加作業は必要ありません

3つ目についてはどういったメリットなのかはあまり汲み取れていません…
どなたか分かる方コメントなどでおしえていただけると嬉しいです

悪い点

  • そのクラスを継承した際に、派生クラスからsuper.XXXでアクセスすることができません
  • そのメソッドは事前にバインドされ、型安全ではないコントラクトがクラスとコンシューマの間で追加されることはありません
    • 原文: The exact semantics of which methods are "pre-bound" and which aren't create an additional non-typesafe contract between the class and its consumers

正直2つ目はよく意味がわかりませんでした…(ダメダメだ
どなたか分かる方コメントなどでおしえていただけると嬉しいです(2度目)

いい点 かつ 悪い点

この方法だと、クラスインスタンスを作るたびに、クロージャが作成されてしまいます。
もし普通のインスタンスメソッドとしてしか実行しなのであれば、この実装方法は過剰すぎます。
ただし、このメソッドをコールバック関数としてよく使うのであれば、
その都度クロージャを作るよりもこのほうが良いでしょう

Local Fat Arrow

その都度クロージャを作ってあげるパターンです。

var x = new SomeClass();
someCallback((n, m) => x.doSomething(n, m));

いい点

  • これは100%型安全です!
  • ECMAScript3でも動きます
  • インスタンス名の記述が1度いいです

悪い点

  • パラメータを2度記述しないといけません
  • 可変長引数可変長引数を利用する場合動作しません

いい点 かつ 悪い点

パフォーマンス/メモリついてはインスタンス関数と比較すると正反対です
(こちらの方がメモリは使わないが、少しパフォーマンスが悪い)

まとめ

一応元記事にはFunction.bindについての記載もあったのですが、
現時点で型安全ではないので、採用はないかなと思います。

19
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
15