yaakaito.org

JavaScriptの似非オーバーロードが気に入らない

JavaScript

【補足】あんまり良い文章ではないので、僕はこう思ってるよ、くらいで読んでください。

こんにちは!うきょーです。 なんかJavaScriptで似非オーバーロードとか省略可能引数使う人結構いますよね。かっこいいですか、そうですか。 僕これ嫌いなんで、書いておこうと思います。

実際によくあるコード

こういうコードがよくありますかね、BackboneとかでもEvents.offとかがこうなってます。

1
2
3
4
5
6
7
8
function(a) {
  if (a) {
    // aを使った処理
  }
  else {
    // 引数がないと判定された時の処理
  }
}

他にも、引数によって挙動が違うのたくさんありますよね、jQueryとかjQueryとかjQueryとか。

まずもって間違っている

上の例の場合、f()f(undefined) を区別する事は出来ません。 f() で期待される挙動は f(undefined) で期待される挙動とは、異なるはずですよね。

これはargumentsを見る事である程度解決できます。

1
2
3
4
5
6
function(a) {
  if (argument.length === 0) {
    // 引数がないときの処理
  }
  // その他
}

この件に関して、ちょうどSpineのコードを読んでいて、イラッとしたのでプルリクしました。 無事にdevにマージされたみたいなので良かったですね。

【補足】勘違いのないように

@kazuhoさんからこんなコメントをもらって、確かにそう読めると思ったので補足する。

正論なんだけど、それ以前に、そもそも引数としてundefined渡すのが間違い。null使うべき

これは、f()f(hoge)で挙動が違うことを前提にしているのであれば、その実装は正確には間違っている(f(undefined)も引数一つとして扱われるべき)、という主張です。 undefinedを使って書いているのは、省略されたときにその引数はundefinedになるのだから、 その方が問題としていることが分かりやすいだろう、という意図があってです。

@kazuhoさんがおっしゃっているように、そもそもundefinedを入れない事が前提があって、 だからundefinedであると判定することにメリットがある、というのはもちろんその通りだと思います。

単純に、僕が嫌だなーと思っていることなので、そこで勘違いが起こってしまっても意味はないなと思うので、補足しました。

挙動を変えないでください

そもそも同じ関数で複数の挙動を持つなと言いたい。 少なくとも僕は、そんな挙動を信じられるほど頭がよくない。

jQueryでよくあるけど、$がいろいろ出来すぎて、XSS出してますよね。

他にも、省略することで返ってくるもののスコープが大きくなっていく関数とかよくありますよね、嫌いです。

別にかっこよくも見やすくもないです

なんでこうやってるのか知らないですけど、ダサいと思ってます。 offとか、offAlloffに分けてもらった方が分かりやすいです。 $もセレクトだけでいいです。作らないでください。

省略可能引数はオブジェクトを渡してください

省略可能引数は、

1
2
3
4
f(a, b, {
  c : c,
  d : d
});

という形式で書かれるべきです。

挙動が異なる関数は分けください

1
2
$select();
$create();

とか

1
2
elem.html();
elem.setHtml():

とか

1
2
Events.unbind();
Events.unbindAll();

にしてください。

どっちの方が挙動を推測しやすいかは一目瞭然だと思いますし、僕はコードゴルフがしたいわけじゃありません。