モーリーのメモ

アプリ開発等(プログラミング、CG作成)、興味を持ったことを実践してまとめるブログです。

モーリーのメモ

『var』と『let』、『==』と『===』の違い:JavaScript

 『Cocos Creator』のコードエディタは簡単な構文チェックをしてくれます。
 このエディタでコードを書いていると、今まで使っていた『Cocos Code IDE』では何も言われなかった所で警告が出たりします。
 
 今回はこの警告がきっかけで調べた、『var』と『let』、『==』と『===』(『!=』と『!==』)の違いについてまとめました。

使用環境

 私が使用している環境です。

  • Mac OS X El Capitan Version 10.11.4
  • Cocos Creator Version 1.0.1
  • ブラウザ:Google Chrome Version 50.0.2661.86 (64-bit)

varとletの違い

 そもそもletの存在を知らなかったのですが、
 varは、関数スコープ
 letは、ブロックスコープ
 です。
 具体的な例で説明します。

varの場合

var a = 1;
cc.log("a = %d", a); // 『a = 1』と出力される
{
    var a = 2; 
    cc.log("a = %d", a); // 『a = 2』と出力される
}
cc.log("a = %d", a); // 『a = 2』と出力される

 同一関数内なので、aはずっと同じaです。
 実行されますが、2回目の『var a = 2; 』は、もうaは定義してるぞ!と注意されます。

letの場合

let a = 1;
cc.log("a = %d", a); // 『a = 1』と出力される
{
    let a = 2; 
    cc.log("a = %d", a); // 『a = 2』と出力される
}
cc.log("a = %d", a); // 『a = 1』と出力される

 ブロックの外と内のaは別物です。
 何も怒られません。
 
 これに気付かされたのは、for文を2回使った時です。

for (var i = 0; i < 5; i++) {
    cc.log("%d", i)
}

for (var i = 0; i < 10; i++) { // ここで、もうiは定義してるぞ!と注意されます。
    cc.log("%d", i)
}

 これ2重定義だったんですね。
 気付かず書いていました。これに限れば特に問題は起きなさそうですが、for文はletが良さそうです。

letは新しいぽい(ES2015/通称ES6から)

 ECMASCriptは、ブラウザごとだったJavasScriptの仕様を標準化して、互換性を高めるための言語仕様です。
 そのECMASCriptの6th Edition(ES6)で、letが追加されたそうです。
 ES6は通称で、正式名称はECMAScript 2015(ES2015)らしいです。ややこしいですが、年数にしたのは毎年変えていくぞという意気込みの表れらしいです。
 ES2015は、2015年の6月に策定とあります。
 let以外にも、const等追加されてるようです。

即時関数でスコープ範囲を限定する

 letが追加されたので使うことはないかもしれませんが、今までは変数のスコープ範囲を限定するために即時関数を使っていたようです。
 即時関数は関数を定義すると同時に実行するための構文です。無名関数とも呼ばれるみたいです。

var a = 1;
cc.log("a = %d", a); // 『a = 1』と出力される
(function () {
    var a = 2; // 怒られません。
    cc.log("a = %d", a); // 『a = 2』と出力される
}());
cc.log("a = %d", a); // 『a = 1』と出力される

letの時と同じように出力されます。

『==』と『===』の違い(『!=』と『!==』の違い)

 『==』と『!=』は、等価演算子
 『===』と『!==』は、厳密等価演算子
 です。
 具体的な例で説明します。

『==』の場合

// 数値と文字列の比較
if(1 == "1"){ // trueになる
    cc.log("trueだよ"); // こっちが実行される
}else{
    cc.log("falseだよ");
}

// booleanと数値の比較
if(true == 1){ // trueになる
    cc.log("trueだよ"); // こっちが実行される
}else{
    cc.log("falseだよ");
}

// booleanと文字列の比較
if(true == "1"){ // trueになる
    cc.log("trueだよ"); // こっちが実行される
}else{
    cc.log("falseだよ");
}

// nullとundefined
if(null == undefined){ // trueになる
    cc.log("trueだよ"); // こっちが実行される
}else{
    cc.log("falseだよ");
}

 『==』では、型変換して比較します。
 上記で『==』を『!=』にした場合、全部falseになります。

『===』の場合

// 数値と文字列の比較
if(1 === "1"){ // falseになる
    cc.log("trueだよ");
}else{
    cc.log("falseだよ"); // こっちが実行される
}

// booleanと数値の比較
if(true === 1){ // falseになる
    cc.log("trueだよ");
}else{
    cc.log("falseだよ"); // こっちが実行される
}

// booleanと文字列の比較
if(true === "1"){ // falseになる
    cc.log("trueだよ");
}else{
    cc.log("falseだよ"); // こっちが実行される
}

// nullとundefined
if(null === undefined){ // falseになる
    cc.log("trueだよ");
}else{
    cc.log("falseだよ"); // こっちが実行される
}

 『===』では、型も比較します。
 上記で『===』を『!==』にした場合、全部trueになります。
 
 これも意識せず使ってました。
 『Cocos Creator』では、基本的に『==』を使うと怒られます。 
 
 このサイトが詳しいです。
www.atmarkit.co.jp

あとがき

 即時関数でスコープ範囲を限定するというのは、知っておくと過去のソースを読むのに役立ちそうです。
 逆に知らないと何で関数にしてるのか意味が分からなかったかもしれません。
 
 新しい構文は、便利なものは取り入れていきたいですが、コンパイラとブラウザの対応状況に注意しないといけないですね。