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?
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 .
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.
==
jest o wiele lepsze, jeśli chodzi o zbadanie go.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**
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
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