Używam JSLint, aby przejść przez JavaScript, i zwraca wiele sugestii, aby zastąpić ==
(dwa znaki równości) znakiem ===
(trzy znaki równości) podczas robienia rzeczy takich jak porównywanie idSele_UNVEHtype.value.length == 0
wewnątrz if
instrukcji.
Czy istnieje korzyści wydajność do zastąpienia ==
z ===
?
Wszelkie ulepszenia wydajności byłyby mile widziane, ponieważ istnieje wielu operatorów porównania.
Jeśli konwersja typu nie ma miejsca, czy nastąpiłby wzrost wydajności ==
?
=== vs ==
, ale w PHP, można przeczytać tutaj: stackoverflow.com/questions/2401478/hy-is-faster-than-in-php/...===
jest znacznie szybszy niż==
. jsperf.com/comparison-of-comparisons===
over==
. W rzeczywistości test porównawczy nie pokazuje dużej różnicy między obydwoma w nowoczesnych przeglądarkach. Osobiście zwykle używam==
wszędzie, chyba że naprawdę potrzebuję ścisłej równości.===
i==
: youtube.com/... Jeśli nie gra, to o 15:20Odpowiedzi:
Operator ścisłej równości (
===
) zachowuje się identycznie jak abstrakcyjny operator równości (==
), z tym wyjątkiem, że nie jest wykonywana konwersja typów, a typy muszą być takie same, aby można je było uznać za równe.Odniesienia: Samouczek Javascript: Operatory porównania
==
Operator będzie porównać do równości po wykonaniu niezbędnych konwersje typów .===
Operator nie zrobić konwersję, więc jeśli dwie wartości nie są tego samego typu===
po prostu wrócićfalse
. Oba są równie szybkie.Cytując doskonały JavaScript Douglasa Crockforda : The Good Parts ,
Aktualizacja:
Punkt dobry był wychowywany przez @Casebash w komentarzach iw @Phillipe Laybaert za odpowiedziami dotyczące obiektów. Dla obiektów
==
i===
działaj zgodnie ze sobą (z wyjątkiem szczególnych przypadków).Szczególny przypadek ma miejsce, gdy porównujesz operację podstawową z obiektem, który ocenia tę samą operację podstawową, ze względu na jej metodę
toString
lubvalueOf
metodę. Rozważmy na przykład porównanie prymitywu łańcucha z obiektem łańcucha utworzonym za pomocąString
konstruktora.Tutaj
==
operator sprawdza wartości dwóch obiektów i zwracatrue
, ale===
widzi, że nie są tego samego typu i zwracająfalse
. Który jest prawidłowy? To naprawdę zależy od tego, co próbujesz porównać. Radzę całkowicie ominąć pytanie i po prostu nie używajString
konstruktora do tworzenia obiektów łańcuchowych z literałów łańcuchowych.Odwołanie
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
źródło
Korzystanie z
==
operatora ( równość )Korzystanie z
===
operatora ( tożsamość )Wynika to z faktu, że operator równości
==
dokonuje przymusu typu , co oznacza, że interpreter niejawnie próbuje przekonwertować wartości przed porównaniem.Z drugiej strony operator tożsamości
===
nie stosuje przymusu typu , a zatem nie konwertuje wartości podczas porównywania, a zatem jest szybszy (zgodnie z tym testem porównawczym JS ), ponieważ pomija jeden krok.źródło
==
„abstrakcyjną równością” i===
„ścisłą równością”. Przyznanie==
jakiegokolwiek rodzaju „równości” jest okropne, ponieważ nie jest przechodnie, ale po co się spierać? Mam jednak więcej problemów z „tożsamością”; Myślę, że ten termin jest dość mylący, choć „działa”. A tak na poważnie, kto ukuł termin „tożsamość”? Przeszukuję standard i nie mogłem go znaleźć.Interesujące obrazowe przedstawienie porównania równości między
==
i===
.Źródło: http://dorey.github.io/JavaScript-Equality-Table/
var1 === var2
var1 == var2
źródło
x == null
aby sprawdzić, czyx
jestnull
lubundefined
.==
vs===
. Duże i małe litery i tak są nierówne i powrócąfalse
zarówno z operatorem, jak==
i z===
operatorem. Ponadto, słowa kluczowetrue
,false
,undefined
,null
,Infinity
istnieją w JS tylko w jednym przypadku i nie może być stosowany w górnych lub mieszanych przypadkach.W odpowiedziach tutaj nie czytałem nic o tym, co oznacza równość . Niektórzy powiedzą, że
===
to znaczy równe i tego samego typu , ale to nie jest tak naprawdę prawda. W rzeczywistości oznacza to, że oba operandy odnoszą się do tego samego obiektu lub, w przypadku typów wartości, mają tę samą wartość .Weźmy następujący kod:
Tak samo tutaj:
Lub nawet:
To zachowanie nie zawsze jest oczywiste. W tej historii jest coś więcej niż równość i bycie tego samego rodzaju.
Reguła jest następująca:
Dla typów wartości (numery):
a === b
Zwraca TRUE jeślia
ib
mają taką samą wartość i są tego samego typuDla typów referencyjnych:
a === b
zwraca true, jeślia
ib
odwołuje się do dokładnie tego samego obiektuCiągów:
a === b
Zwraca true jeślia
ib
to zarówno ciągi i zawierają dokładnych samych znakówCiągi: przypadek specjalny ...
Łańcuchy nie są typami wartości, ale w Javascripcie zachowują się jak typy wartości, więc będą „równe”, gdy znaki w łańcuchu będą takie same i gdy będą tej samej długości (jak wyjaśniono w trzeciej regule)
Teraz staje się interesujący:
A co powiesz na to ?:
Myślałem, że łańcuchy zachowują się jak typy wartości? Cóż, zależy od kogo zapytasz ... W tym przypadku aib nie są tego samego typu.
a
jest typuObject
, natomiastb
jest typustring
. Pamiętaj tylko, że utworzenie obiektu łańcucha za pomocąString
konstruktora powoduje utworzenie czegoś typu,Object
który przez większość czasu zachowuje się jak łańcuch .źródło
new Number() == "0"
. Również w przeglądarce Firefox:(function(){}) == "function () {\n}"
new String("123") !== "123"
. Są to różne typy. Proste, ale mylące.String
obiekty zachowują się tak samo, jak każdy inny obiekt .new String
nigdy nie powinien być używany, ponieważ nie tworzy to prawdziwych ciągów. Prawdziwy ciąg znaków i można go tworzyć za pomocą literałów lub wywoływaniaString
jako funkcji beznew
, na przykład:String(0); //"0", Real string, not an object
Pozwól mi dodać tę radę:
W razie wątpliwości przeczytaj specyfikację !
ECMA-262 to specyfikacja języka skryptowego, którego JavaScript jest dialektem. Oczywiście w praktyce ważniejsze jest zachowanie najważniejszych przeglądarek niż ezoteryczna definicja tego, jak należy postępować. Ale pomocne jest zrozumienie, dlaczego nowy ciąg („a”)! == „a” .
Pozwól mi wyjaśnić, jak przeczytać specyfikację, aby wyjaśnić to pytanie. Widzę, że w tym bardzo starym temacie nikt nie miał odpowiedzi na bardzo dziwny efekt. Jeśli więc potrafisz przeczytać specyfikację, pomoże ci to w swoim zawodzie. Jest to umiejętność nabyta. Kontynuujmy.
Przeszukiwanie pliku PDF dla === prowadzi mnie do strony 56 specyfikacji: 11.9.4. The Strict Equals Operator (===) , a po przejściu przez specyfikację znajduję:
Interesujący jest krok 11. Tak, łańcuchy są traktowane jako typy wartości. Ale to nie wyjaśnia, dlaczego nowy ciąg („a”)! == „a” . Czy mamy przeglądarkę niezgodną z ECMA-262?
Nie tak szybko!
Sprawdźmy typy operandów. Wypróbuj sam, zawijając je w typeof () . Uważam, że nowy ciąg znaków („a”) jest obiektem i używany jest krok 1: zwróć false, jeśli typy są różne.
Jeśli zastanawiasz się, dlaczego nowy ciąg („a”) nie zwraca ciągu, co powiesz na jakieś ćwiczenie polegające na czytaniu specyfikacji? Baw się dobrze!
Aidiakapi napisał to w komentarzu poniżej:
new zawsze zwraca Object, nawet dla konstruktorów String . I niestety! Semantyka wartości dla łańcuchów (patrz krok 11) zostaje utracona.
A to w końcu oznacza: nowy ciąg („a”)! == „a” .
źródło
new String('x')
, ponieważ nigdy nie widziałem żadnego kodu w środowisku naturalnym, który używa prymitywnych obiektów otoki i nie sądzę, aby istniał dobry powód, szczególnie w dzisiejszych czasach. Czy kiedykolwiek napotkałeś kod, który to robi?new String()
.new String()
to prawdopodobnie najmniejsze z twoich zmartwień. Rozumiem obawy w teorii, ale czy masz jakieś przykłady z prawdziwego świata? Dla mnie to jak stary niepokój, że ktoś mógłby ustawićundefined
inną wartość.W PHP i JavaScript jest to operator ścisłej równości. Co oznacza, że porówna zarówno typ, jak i wartości.
źródło
var a = {}, b = {};
a == b
zwraca wartość false.var a = {}, b = {};
Chociaż oba sąa
ib
rzeczywiście oba są przedmiotem, ale technicznie rzecz biorąc nie są one tej samej wartości. Są to różne przypadki. Pamiętaj, że porównywanie instancji zachowuje się inaczej niż porównywanie operacji podstawowych. Co prawdopodobnie przyczynia się do tego zamieszania. Podobne zachowanie porównawcze zobaczysz, jeśli użyjesz wersji instancji pierwotnych typów danych. Npnew String('asdf')
lubnew Number(5)
. Np .:new Number(5) == new Number(5)
jest fałszywe, mimo że mają tę samą wartość.Przetestowałem to w Firefoksie z Firebug, używając następującego kodu:
i
Moje wyniki (przetestowane pięć razy i uśrednione):
Powiedziałbym więc, że drobna różnica (pamiętaj, że to ponad 100 000 iteracji) jest znikoma. Wydajność nie jest powodem do zrobienia
===
. Wpisz bezpieczeństwo (cóż, tak bezpieczne, jak to możliwe w JavaScript), a jakość kodu to.źródło
==
nie zgadzasz.==
operator ma rzeczywistą kooperację typów ? Pamiętaj, że wtedy następuje wzrost wydajności.===
nadużywania,==
ale mylisz się, że ich wydajność jest zasadniczo równa i że uważasz, że ten test dowodzi, że i że wiele innych osób zgodziło się, jest dla mnie całkowicie absurdalne.W JavaScript oznacza tę samą wartość i typ.
Na przykład,
ale
źródło
=== operatora nazywana jest ścisłe operatora porównania, nie różnią się od == operatora.
Weźmy 2 zmienne a i b.
Aby „a == b” mogło zostać ocenione jako prawda, aib musi mieć tę samą wartość .
W przypadku „a === b” aib muszą mieć tę samą wartość, a także ten sam typ, aby mógł zostać oceniony jako prawdziwy.
Weź następujący przykład
Podsumowując ; użycie operatora == może dać wartość true w sytuacjach, w których nie chcesz, więc użycie operatora === byłoby bezpieczniejsze.
W scenariuszu użycia 90% nie będzie miało znaczenia, którego używasz, ale dobrze jest znać różnicę, gdy pewnego dnia otrzymasz nieoczekiwane zachowanie.
źródło
Dlaczego
==
jest tak nieprzewidywalny?Co otrzymujesz, porównując pusty ciąg
""
z liczbą zero0
?true
Tak, zgadza się
==
to z pustym ciągiem, a liczba zero to ten sam czas.I to się nie kończy, oto kolejny:
Z tablicami robi się naprawdę dziwnie.
Potem dziwniejsze ze sznurkami
Pogarsza się:
Kiedy równość nie jest równa?
Powiem to jeszcze raz:
A to tylko szalone rzeczy, które dostajesz z prymitywami.
To zupełnie nowy poziom szaleństwa, gdy używasz
==
przedmiotów.W tym momencie prawdopodobnie zastanawiasz się ...
Dlaczego to się dzieje?
Jest tak, ponieważ w przeciwieństwie do „triple equals” (
===
), który sprawdza tylko, czy dwie wartości są takie same.==
robi całą masę innych rzeczy .Ma specjalną obsługę dla funkcji, specjalną obsługę dla wartości zerowych, niezdefiniowanych, ciągów, jak to nazwiesz.
Robi się dziwnie.
W rzeczywistości, jeśli spróbujesz napisać funkcję, która robi to
==
, co by wyglądała, wyglądałby mniej więcej tak:Co to znaczy?
Oznacza
==
to, że jest skomplikowane.Ponieważ jest to skomplikowane, trudno jest wiedzieć, co się stanie, gdy go użyjesz.
Co oznacza, że możesz skończyć z błędami.
Morał tej historii to ...
Spraw, aby twoje życie było mniej skomplikowane.
Użyj
===
zamiast==
.Koniec.
źródło
looseEqual
jest zły.Function == Function.toString()
to prawda, alelooseEqual(Function, Function.toString())
fałszem. Nie wiesz, dlaczego odfiltrowujesz funkcje na początku.typeof x === "object"
sprawdzeniu, czy jest to obiekt, ale `typeof działa tylko dla prymitywów niepustych. Być może zainteresuje Cię moja lista właściwych sposobów sprawdzania, czy wartość jest obiektem(function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}
- sprawdź ten JS Fiddle, który uruchamia wszystkie testy: jsfiddle.net/luisperezphd/7k6gcn6g (tam 1225 permutacji testowych)==
robi wiele rzeczy, co bardzo utrudnia przewidywanie wyników, a jednocześnie===
jest o wiele prostszy i przewidywalny, co jest jednym z głównych powodów, dla===
których zalecany jest wybór. (Dodam notatkę do odpowiedzi, w której wspominasz o swoim punkcie)===
sprawdza, czy te same strony są równe pod względem rodzaju i wartości .Przykład:
Typowy przykład:
Kolejny częsty przykład:
Wiele razy na bez typu check byłby przydatny, bo nie obchodzi mnie, jeśli wartość jest albo
undefined
,null
,0
lub""
źródło
'string' !== 'number'
Schemat blokowy wykonania JavaScript dla ścisłej równości / porównania '==='
Schemat blokowy wykonania JavaScript dla nie ścisłej równości / porównania „==”
źródło
string
strzałka wskazuje duże szare pole, czy to znaczy, że przerywacz rzuca ciąg na liczbę?string
ma być porównywany z typemnumber
, więc przerywacz patrzy na to, co łańcuch powinien być porównywany i odpowiednio rzutuje?ToNumber
, co powróci, gdy otrzyma różne typy, więc jeśli otrzyma ciąg, wybierze tylko ostatnią opcję (i zamieni ją na liczbę).==
używaToNumber
tylko w przypadkachstring == number
lubboolean == anything
powyżej (i tylko nastring
/boolean
). Środek ten==
nie będzie konwertowaćundefined
lubnull
chociaż są one w szarym polu. (Dla dowolnej kombinacji jednegoundefined
lubnull
obu==
będzie zawsze zwracaćtrue
. Również to, czy wartość jest po lewej czy po prawej stronie, nie ma znaczenia,==
(i===
) zwróci ten sam wynik.)JavaScript
===
vs==
.źródło
Oznacza to równość bez przymusu typu przymus typu oznacza, że JavaScript nie konwertuje automatycznie żadnych innych typów danych na typy danych łańcuchowych
źródło
W typowym skrypcie nie będzie różnicy w wydajności. Ważniejszy może być fakt, że tysiąc „===” jest o 1 KB większy niż tysiąc „==” :) Profile JavaScript mogą ci powiedzieć, czy w twoim przypadku występuje różnica w wydajności.
Ale osobiście zrobiłbym to, co sugeruje JSLint. To zalecenie nie występuje z powodu problemów z wydajnością, ale dlatego, że wymuszenie typu
('\t\r\n' == 0)
jest prawdziwe.źródło
Operator równego porównania == jest mylący i należy go unikać.
Jeśli MUSZĄ żyć z nim, a następnie zapamiętać następujące 3 rzeczy:
RÓWNY TABELA PRAWDY OPERATORA W JAVASCRIPT
** DZIWNY: zwróć uwagę, że dowolne dwie wartości w pierwszej kolumnie nie są równe w tym sensie. **
źródło
Prawdopodobnie nie będzie żadnej różnicy w wydajności między tymi dwiema operacjami w twoim użyciu. Nie ma potrzeby konwersji typu, ponieważ oba parametry są już tego samego typu. Obie operacje będą miały porównanie typów, a następnie porównanie wartości.
źródło
Tak! To ma znaczenie.
===
operator w javascript sprawdza wartość, a także typ, w którym jako==
operator sprawdza tylko wartość (w razie potrzeby dokonuje konwersji typu) .Możesz to łatwo przetestować. Wklej następujący kod do pliku HTML i otwórz go w przeglądarce
Otrzymasz „ fałsz ” w pogotowiu. Teraz zmodyfikuj
onPageLoad()
metodę, abyalert(x == 5);
się spełniła .źródło
===
operator sprawdza wartości, a także typy zmiennych pod kątem równości.==
operator sprawdza tylko wartość zmiennych pod kątem równości.źródło
To ścisły test kontrolny.
To dobrze, zwłaszcza jeśli sprawdzasz między 0 a fałszem i null.
Na przykład, jeśli masz:
Następnie:
Wszystkie zwracane są prawdą i możesz tego nie chcieć. Załóżmy, że masz funkcję, która może zwrócić 0. indeks tablicy lub false w przypadku awarii. Jeśli sprawdzisz za pomocą „==” false, możesz uzyskać mylący wynik.
Więc z tym samym co powyżej, ale z surowym testem:
źródło
0 != null
. -1JSLint czasami daje nierealistyczne powody do modyfikacji rzeczy.
===
ma dokładnie taką samą wydajność jak==
jakby typy były już takie same.Jest szybszy tylko wtedy, gdy typy nie są takie same, w którym to przypadku nie próbuje konwertować typów, ale bezpośrednio zwraca wartość false.
Więc IMHO, JSLint może być użyte do napisania nowego kodu, ale za wszelką cenę należy unikać niepotrzebnej nadmiernej optymalizacji.
Czyli, nie ma powodu, aby zmienić
==
się===
w kontroli jakif (a == 'test')
gdy wiesz to na fakt, że może być tylko String.Modyfikacja dużej ilości kodu w ten sposób marnuje czas programistów i recenzentów i nic nie osiąga.
źródło
Po prostu
==
oznacza porównanie operandów ztype conversion
I
===
oznacza porównanie operandów beztype conversion
Konwersja typów w javaScript oznacza, że javaScript automatycznie konwertuje wszystkie inne typy danych na typy danych łańcuchowych.
Na przykład:
źródło
Prostym przykładem jest
źródło
Dwie najlepsze odpowiedzi, o których mowa, == oznacza równość, a === oznacza tożsamość. Niestety to stwierdzenie jest nieprawidłowe.
Jeśli oba operandy == są obiektami, są one porównywane w celu sprawdzenia, czy są tym samym obiektem. Jeśli oba operandy wskazują ten sam obiekt, operator równości zwraca wartość true. W przeciwnym razie dwa nie są równe.
W powyższym kodzie zarówno ==, jak i === stają się fałszywe, ponieważ aib nie są tymi samymi obiektami.
To znaczy: jeśli oba operandy == są obiektami, == zachowuje się tak samo jak ===, co oznacza również tożsamość. Zasadnicza różnica między tymi dwoma operatorami polega na konwersji typu. == ma konwersję, zanim sprawdzi równość, ale === nie.
źródło
Zasadniczo wolałbym używać
===
zamiast==
(i!==
zamiast!=
).Powody są wyjaśnione w odpowiedziach powyżej, a także Douglas Crockford jest całkiem jasny ( JavaScript: The Good Parts ).
Istnieje jednak jeden wyjątek :
== null
jest skutecznym sposobem sprawdzenia, czy „jest zerowy lub niezdefiniowany”:Na przykład jQuery 1.9.1 używa tego wzorca 43 razy, a moduł sprawdzania składni JSHint zapewnia nawet
eqnull
opcję relaksacyjną z tego powodu.Z przewodnika po stylu jQuery :
źródło
Problem polega na tym, że możesz łatwo wpaść w kłopoty, ponieważ JavaScript ma wiele niejawnych konwersji, co oznacza ...
Który wkrótce stanie się problemem. Najlepszą próbkę tego, dlaczego niejawna konwersja jest „zła”, można pobrać z tego kodu w MFC / C ++, który faktycznie skompiluje się z powodu niejawnej konwersji z CString na UCHWYT, który jest typem wskaźnika typu ...
Co oczywiście podczas działania robi bardzo nieokreślone rzeczy ...
Google za niejawne konwersje w C ++ i STL, aby uzyskać niektóre argumenty przeciwko niemu ...
źródło
0 == null
to fałsz.Z podstawowego odniesienia do javascript
źródło
Porównanie równości:
Operator
==
Zwraca true, gdy oba operandy są równe. Przed porównaniem operandy są konwertowane na ten sam typ.
Porównanie równości i typów:
Operator
===
Zwraca wartość true, jeśli oba operandy są równe i tego samego typu. Ogólnie jest to lepsze i bezpieczniejsze, jeśli porównasz w ten sposób, ponieważ nie ma konwersji typu „za kulisami”.
źródło
Oto przydatna tabela porównawcza, która pokazuje konwersje, które mają miejsce, oraz różnice między
==
i===
.Jak stwierdza wniosek:
http://dorey.github.io/JavaScript-Equality-Table/
źródło
zerowe i nieokreślone są nicością, to znaczy
Tutaj
a
ib
nie mają wartości. Natomiast 0, false i „” są wartościami. Jedną wspólną cechą między nimi jest to, że wszystkie są wartościami fałszowania, co oznacza, że wszystkie spełniają warunki fałszowania.Zatem 0, fałsz i „” razem tworzą podgrupę. Z drugiej strony, null i undefined tworzą drugą podgrupę. Sprawdź porównania na poniższym obrazku. zero i nieokreślone byłyby równe. Pozostałe trzy będą sobie równe. Ale w JavaScript wszystkie są traktowane jako warunki do fałszowania.
Jest to to samo, co każdy obiekt (jak {}, tablice itp.), Niepuste ciągi i logiczna prawda są warunkami prawdziwymi. Ale nie wszystkie są równe.
źródło