41

私はDouglas Crockford のJavaScript: The Good Partsを読んでいて、私には意味をなさないこの奇妙な例に出くわしました:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == undefined  // false
false == null       // false
null == undefined   // true

著者はまた、「決して and を使用しない==!=ください。代わりに、常に and を使用===してください」と述べてい!==ます。しかし、彼はなぜ上記の行動が示されるのか説明していませんか? 私の質問は、なぜ上記の結果がそのままなのかということです。JavaScript では推移性が考慮されていませんか?

4

3 に答える 3

33
'' == '0' // false

左側は空の文字列で、右側は1文字の文字列です。2つの同一でない文字列を比較しているため、これらは誤りです(Niallに感謝します)。

0 == '' // true

したがって、これが真である理由0は、がであり、空の文字列がであるためです。

0 == '0' // true

これは少しトリッキーです。仕様では、オペランドが文字列と数値の場合、文字列を数値に強制することが規定されています。'0'になり0ます。ありがとうsmfoote

false == undefined // false

この値undefinedはJavaScriptで特別であり、。以外の値と同じではありませんnull。しかし、それは偽物です。

false == null // false

繰り返しnullますが、特別です。に等しいだけundefinedです。それも偽物です。

null == undefined // true

nullundefined似ていますが、同じではありません。null何も意味しませんが、undefined変数の値は設定されていないか、存在しません。それらの値が等しいと見なされることは、ある意味で理にかなっています。

あなたが本当に混乱したいなら、これをチェックしてください...

'\n\r\t' == 0

空白のみで構成される文字列は0に等しいと見なされます。

ダグラス・クロックフォードはたくさんの推薦をします、しかしあなたはそれらを福音としてとらえる必要はありません。:)

TJ Crowderは、 ECMAScript言語仕様を研究して、これらの同等性テストの背後にある全体像を知るための優れた提案をしています。

参考文献?

スペック

yolpo(偽の値について)

于 2011-03-27T04:14:34.480 に答える
4

実際にそのように動作する JavaScript 関数を作成すると、その動作==についてある程度の洞察が得られるはずです。

ここで私が何を意味するかを示すために、その関数は次のとおりです。

// loseEqual() behaves just like `==`
function loseEqual(x, y) {
    // notice the function only uses "strict" operators 
    // like `===` and `!==` to do comparisons

    if(typeof y === typeof x) return y === x;

    if(typeof y === "function" || typeof x === "function") return false;

    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);

    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;

    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

ご覧のとおり==、型変換には多くの複雑なロジックがあります。そのため、どのような結果が得られるかを予測することは困難です。

予期しない結果の例を次に示します。

予期せぬ真実

[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true

'\r\n\t' == 0 // returns true

予期せぬ結論

// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true

// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true

// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**

特別な機能を持つオブジェクト

// Below are examples of objects that
// implement `valueOf()` and `toString()`

var objTest = {
    toString: function() {
        return "test";
    }
};

var obj100 = {
    valueOf: function() {
        return 100;
    }
};

var objTest100 = {
    toString: function() {
        return "test";
    },
    valueOf: function() {
        return 100;
    }
};

objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true

objTest100 == "test" // returns **FALSE**
于 2016-08-09T17:41:15.763 に答える