Javascriptのぐぬぬ感 – いろんな言語との比較を添えて


システム技術グループ S.Y

こんにちは。
今日は少し趣向を変えて等価演算子の話を一つ。

弊社のグループウェア上で少し盛り上がった話なのですが、Javascriptの等価演算子って妙な動きをするんですよね。

例えば、

var a = 1; // 1はNumber
var b = ‘1’; // 1はString

a == b;
-> true

a === b;
-> false

こんなの。
型判定がきつい言語出身の人が見たら、蕁麻疹出そうですね。
とりあえず、値比較したいときは厳密な等価演算子(===)を使えってところでしょうか。
ここらへんMDNにどんな場合true、falseどっちが返ってくるのか詳しく書かれてて、今更ながら面白いです。

で、そんなことを話すきっかけになったのが、とある同僚がVBScriptでは等価演算子はイコール1個でJSはイコール2個で頭痛いって言ってたことでした。

個人的にはVBScriptのイコール1個の等価演算子に「ふぁっ!!!????」ってなってたのですが、じゃあ、他の言語ってここらへんどうなってんだろ、と思い、まとめてみます。

■VBScriptの変数代入

いきなり脱線であれなのですが、VBScript、イコール1個が等価演算子なら、変数代入どうすんねんと思いまして、調べてみました。
そうしたところ・・・・。

Dim str ->変数の宣言
str = “文字列” ->変数への値代入

え。
よくよく読んでみると、

If str = “文字列” Then
 ‘trueのときの処理
Else
 ‘falseのときの処理
End If

つまり、条件分岐のときは、(当然っちゃ当然ですが)等価演算子として扱われる、と。
ふむ・・・。

同じ記号が場合によって別の機能果たすのか・・・。紛らわしく・・・ない・・・?

■rubyの場合
閑話休題。ようやく本題行きます。
rubyの場合を見ていきましょう。

・変数宣言/代入
str = “文字列”

・条件分岐
if str == “文字列” then
 #trueのときの処理
else
 #falseのときの処理
end

シンプルですね。好き。

rubyの場合、数値の小数点以下のある無しなどを厳密比較するには比較演算子ではなくて、特定のメソッドを使う必要があります。

1 == 1.0 #true
1 === 1.0 #true
1.eql?(1.0) #false

型は==でも===でもどちらも判断してくれるので、javascript的なぐぬぬ感はないですね。

1 == ‘1’ #false
1 === ‘1’ #false
1 == 1 #true
1 === 1 #true

rubyは組み込みで対話型の実行環境が用意されていますが、pryって便利なのもあるんで、そっちのがよく使います。
gemでさくっと入るのでおすすめ。

■PHPの場合
・変数宣言/代入
$str = “文字列”;

・条件分岐
if ($str == “文字列”) {
 // trueのときの処理
} else {
 // falseのときの処理
}

PHPの厳密比較はjavascriptと同じくイコール3個です。
変数は必ず$始まりっての、わかりやすくて個人的には好きなんですが、どうなんでしょ。

PHPはborisって対話型の実行環境がありまして、少しだけ試したいときなんかはよいですね。
ただ、結構インストールがめんどくて辛い。

■Pythonの場合
・変数宣言/代入
str = ‘文字列’

・条件分岐
if str == ‘文字列’:
 #trueのときの処理
else:
 $falseのときの処理

pythonでは===での比較は行なえません。==で型の比較もしっかりやってくれるので◯です。

と、少ないですが、さくっと3言語の違いを見てみました。
変数や条件分岐といったプログラミング言語なら必ず備えている機能でも、結構ちがいがあるもんですね。
設計思想やらがほの見えてたのしいものです。
今度は関数編なんてのもやるかも。

最後にJavascriptおそるべしと、(弊社内で)話題になっていた「trueのインクリメント」の話をして終わります。

■trueがインクリメントできちゃうんですって!???
これもまた別の同僚から指摘してもらって初めて知ったんですが、Javascriptのtrueって・・・。

true == 1; //true

えー・・・・。マジっすか・・・。

true + true; //2

うそーん・・・・。

というわけで、Javascriptでは真実が増大します!異論は認めない。
真実がインクリメントする関数を作ったので、よろしくご査収ください。

function incrementalTruth(num) {
  var truth = true;
  for(var i = 0; i < num; i++) {     truth += true;   }  return truth; } incrementalTruth(8) //9

本日は以上です。