3.陰的な強制転換に注意する

3462 ワード

JavaScriptはタイプのエラーに対してとてつもなく寛容です.
JavaScriptの中にはごく少数の場合があり、エラーを提供するタイプは適時エラーを発生します.しかし、ほとんどの場合、JavaScriptはエラーを出さずに、多様な自動変換プロトコルに従って、値を希望のタイプに強制的に変換します.
2 + 3; // 5
"hello" + "world"; // "hello world"
"2" + 3; // "23"
2 + "3"; // "23"
1 + 2 + "3"; // "33" === (1 + 2) + "3"; // "33"
1 + "2" + 3; // "123" === (1 + "2") + 3; // "123"
ビット演算子は、演算数を数字に変換するだけでなく、演算数を32ビットの整数に変換します.
"17" * 3; // 51
"8" | "1"; // 9
強制変換もエラーを隠します.結果nullの変数は算術演算で失敗することなく、暗黙的に0に変換されます.定義されていない変数は、特別な浮動小数点値NaN(not a number)に変換されます.
NaN
  • NaNはそれ自体ではなく、一つの値がNaNに等しいかどうかをテストするのは全く通用しません.
  • var x = NaN;
    x === NaN; // false
    
  • 標準のライブラリ関数isNaNは、値が数字であることを知っているときだけ、NaNであるかどうかを検出することができます.
  • isNaN(NaN); // true
    isNaN("foo"); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN({ valueOf: "foo"  }); // true
    
  • NaNはJavaScriptの中で唯一の値であり、その値がNaNであるかどうかを常にチェックすることによってテストすることができる.
  • var a = NaN;
    a !== a; // true
    
    var b = "foo";
    b !== b; // false
    
    var c = undefined;
    c !== c; // false
    
    var d = {};
    d !== d; // false
    
    var e ={ valueOf: "foo"  };
    e !== e; // false
    
    //      
    function isReallyNaN(x) {
      return x !== x;
    }
    
    オブジェクトを元の値に強制的に変換することもできます.
  • は、toString方式により文字列に変換される.
  • "J" + { toString: function() { return "S"; } }; // "JS"
    
  • は、valueOf法によりデジタルに変換される.
  • 2 * { valueOf: function() { return 3; } }; // 6
    
    一方のオブジェクトがtoStringvalueOfの方法を同時に含む場合、演算子+はどの方法を呼び出すべきかは明らかではない.文字列接続をするかそれとも加算をするかはパラメータの種類によるが、暗黙的な強制変換があるので、タイプは明らかではない.JavaScriptは、valueOf方法ではなく、toString方法を盲目的に選択することによって、このような曖昧な状況を解決する.
    var obj = {
      toString: function() {
        return "[object MyObject]";
      },
      valueOf: function() {
        return 17;
       }
    };
    "object: " + obj; // "object: 17"
    // valueOf                    ,      ,toString valueOf           ,      valueOf  ,              。
    
    真値演算if||&&などの演算子論理的には、操作パラメータとしてブール値が必要であるが、実際には任意の値を受け入れることができ、JavaScriptは、単純な暗黙的強制変換規則に従って値をブール値と解釈し、JavaScriptには7つの偽値がある.これ以外のすべての値は本物です.実際の値を使って、関数のパラメータやオブジェクトの属性が定義されているかどうかを確認します.絶対安全ではありません.
    function point(x, y){
      if (!x){
        x = 320;
      }
      if (!y){
        y = 240;
      }
      return { x: x, y: y };
    }
    point(0, 0); // { x: 320, y: 240 }
    
    パラメータがfalseであるかどうかをチェックするより厳しい方法は0を使用することである.
    function point(x, y) {
      if (typeof x === "undefined") {
        x = 320;
      }
      if (typeof y === "undefined") {
        y = 240; 
      }
      return { x: x, y: y };
    }
    //     point         0 undefined。
    point(); // { x: 320, y: 240 }
    point(0, 0); // { x: 0, y: 0 }
    
    //        undefined    。
    if (x === undefined) { ... }
    
    ヒント
  • タイプのエラーは、暗黙的な強制変換によって非表示にされるかもしれない.
  • で再負荷された演算子-0は、加算または文字列接続動作がパラメータの種類に依存します.
  • オブジェクトはNaN方式で強制的に数字に変換され、toString方式で強制的に文字列に変換される.
  • null方法を有するオブジェクトが""方法を実装すべきであり、undefined方法によって生成された数字の文字列表現を返す.
  • は、1つの値が未定義の値であるかどうかをテストし、undefinedを使用するか、またはtypeofと比較するべきであり、真の値を使用して演算するのではない.