JavaScript equality transitivity is weird

Czytałam Douglas Crockford ' s JavaScript: the Good Parts, a ja natknąłem się na ten dziwny przykład, który nie ma dla mnie sensu:

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

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

Autor wspomina również " nigdy nie używać == i !=. Zamiast tego Zawsze używaj === i !==". Nie wyjaśnia jednak, dlaczego powyższe zachowanie jest eksponowane? Więc moje pytanie brzmi, dlaczego powyższe wyniki są takie, jakie są? Czy przechodniość nie jest brana pod uwagę w JavaScript?

Author: jtheletter, 2011-03-27

4 answers

'' == '0' // false

Lewa strona to pusty łańcuch, a prawa strona to łańcuch z jednym znakiem. Są one fałszywe, ponieważ dokonuje porównania dwóch identycznych łańcuchów (dzięki Niall ).

0 == '' // true

Stąd, dlaczego ten jest prawdziwy, ponieważ 0 jest falsy , A pusty ciąg jest falsy.

0 == '0' // true
Ta jest nieco trudniejsza. Spec stwierdza, że jeśli operandami są ciąg znaków i liczba, to wymuszają ciąg znaków na liczbę. '0' staje się 0. Thanks smfoote .
false == undefined // false

Wartość undefined jest wyjątkowa w JavaScript i nie jest równa niczym innym poza null. Jednak jest to falsy.

false == null // false

Znowu, null jest wyjątkowy. Jest tylko równa undefined. Jest również falsy .

null == undefined // true

null i undefined są podobne, ale nie Takie same. null oznacza nic , podczas gdy undefined jest wartością zmiennej nie ustawionej lub nieistniejącej. To miałoby sens. że ich wartości będą uważane za równe.

Jeśli chcesz być naprawdę zdezorientowany, sprawdź to...

'\n\r\t' == 0

Łańcuch składający się tylko z białych znaków jest uważany za równy 0.

Douglas Crockford daje wiele rekomendacji, ale nie musisz ich traktować jako Ewangelię. :)

T. J. Crowder proponuje studiowanie specyfikacji języka ECMAScript, aby poznać całą historię stojącą za tymi równościami testy.

[[18]}Czytaj Dalej?

Spec .

Yolpo (on falsy values)

 28
Author: alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:11

Odpowiedź na to pytanie ma związek z tym, jak JavaScript radzi sobie z przymusem. W przypadku ==, ciągi są wymuszane liczbami . Dlatego:

'' == '0' jest równoważne '' === '0' (oba są ciągami, więc nie jest konieczne przymus).

0 == '' jest równoważne 0 === 0 ponieważ łańcuch '' staje się liczbą 0 (math.abs('') === 0).

0 == '0' jest równoważne 0 === 0 z tego samego powodu.

false == undefined jest równoważne 0 === undefined ponieważ JavaScript wymusza booleans to be numbers when types don ' t match

false == null jest równoważne 0 === null z tego samego powodu.

null == undefined to prawda, ponieważ spec tak mówi.

Dzięki, że zadałeś to pytanie. Moje zrozumienie == jest o wiele lepsze, jeśli chodzi o zbadanie go.
 8
Author: smfoote,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-31 19:30:10

Możesz napisać funkcję JavaScript, która zachowuje się dokładnie tak jak ==, która powinna dać ci wgląd w jej zachowanie.

Aby pokazać, co mam na myśli tutaj jest ta funkcja:

// 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();
}

Jak widać == ma dużo skomplikowanej logiki konwersji typów. Z tego powodu trudno przewidzieć, jaki wynik otrzymasz.

Oto kilka przykładów niektórych wyników, których nie można się spodziewać:

Unexpected Prawdy

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

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

Nieoczekiwane Wnioski

// 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**

Obiekty z funkcjami specjalnymi

// 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**
 4
Author: Luis Perez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 17:41:15

Powodem jest to, że operator identity lub strict ( = = = ) porównuje go z bez konwersji typu, co oznacza, że jeśli obie wartości nie mają tej samej wartości i tego samego typu, nie będą uważane za równe.

Zerknij na ten link, to cię budzi wątpliwości: łatwy sposób na zrozumienie działania operatora tożsamości

 -1
Author: ludico8,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-22 04:00:39