JavaScript 비교에서 어떤 equals 연산자 (== vs ===)를 사용해야합니까?


5665

JSLint 를 사용하여 JavaScript를 사용하고 있으며 명령문 내부를 비교하는 것과 같은 일을 할 때 ==(2 개의 등호)를 ===(3 개의 등호 ) 로 대체하는 많은 제안을 반환 합니다.idSele_UNVEHtype.value.length == 0if

로 대체하면 성능 이점 =====있습니까?

많은 비교 연산자가 존재하므로 성능 향상을 환영합니다.

유형 변환이 수행되지 않으면 성능이 향상 ==됩니까?


134
누구에게 동일한 주제에 관심이있을 수도 === vs ==있지만, PHP에서, 여기 읽을 수 있습니다 : stackoverflow.com/questions/2401478/why-is-faster-than-in-php/...
마르코 Demaio

257
이런 경우에 사람이 2012 년에 궁금 : ===방법 보다 더 빨리 ==. jsperf.com/comparison-of-comparisons
Ry-

25
@minitech 형식 변환을하지 않기 때문에
Umur Kontacı

19
@minitech, 나는 ===이상 을 사용하여 응용 프로그램을 눈에 띄게 빠르게 만들 것 ==입니다. 실제로 벤치 마크는 최신 브라우저에서 두 가지 사이에 큰 차이를 나타내지 않습니다. 개인적으로, 나는 ==엄격한 평등이 정말로 필요한 경우가 아니면 보통 어디에서나 사용 합니다.
laurent

5
여기 크록 포드의의 일부입니다 JS 좋은 부품 그는 설명 이야기 =====연산자 : youtube.com/...는 이 재생되지 않는 경우가에서의 15시 20분
davidhiggins

답변:


6484

엄격한 항등 연산자 ( ===) ==는 형식 변환이 수행되지 않는 것을 제외하고 추상 등호 연산자 ( )와 동일하게 작동 하며 유형이 동일하다고 간주되도록 동일해야합니다.

참조 : Javascript 학습서 : 비교 연산자

==운영자는 어떤지를 비교합니다 필요한 형식 변환을 수행 한 후 . ===운영자는 것입니다 하지 두 값이 동일하지 유형이 그렇다면, 변환을 ===간단하게 돌아갑니다 false. 둘 다 똑같이 빠릅니다.

Douglas Crockford의 뛰어난 JavaScript : The Good Parts 를 인용 하면,

: 자바 스크립트는이 개 평등 사업자의 세트를 가지고 ===!==, 그들의 사악한 쌍둥이 ==!=. 좋은 것은 당신이 기대하는 방식으로 작동합니다. 두 피연산자가 동일한 유형이고 동일한 값을 갖는 경우,를 ===생성 true하고 !==생성합니다 false. 피연산자가 같은 유형일 때 사악한 쌍둥이가 옳은 일을하지만 다른 유형일 경우 값을 강요하려고합니다. 그들이하는 규칙은 복잡하고 기억에 남습니다. 흥미로운 사례는 다음과 같습니다.

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

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

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

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

평등 비교표

전이성의 결여가 놀랍습니다. 내 충고는 결코 사악한 쌍둥이를 사용하지 않는 것입니다. 대신, 항상 사용 ===하고 !==. 방금 표시된 모든 비교 false===연산자로 생성 됩니다 .


최신 정보:

@Casebash 는 주석과 객체에 관한 @Phillipe Laybaert의 답변 에서 좋은 지적을 얻었 습니다 . 객체의 경우, =====(특별한 경우를 제외하고) 서로 지속적으로 행동한다.

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

특별한 경우는 기본 요소 toString또는 valueOf메소드 로 인해 기본 요소를 동일한 기본 요소로 평가되는 오브젝트와 비교하는 경우입니다 . 예를 들어, 문자열 기본 요소와 String생성자를 사용하여 작성된 문자열 오브젝트를 비교해보십시오 .

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

여기서 ==연산자는 두 객체의 값을 확인하고 반환 true하지만 ===, 동일한 유형이 아니고를 반환 false합니다. 어느 것이 맞습니까? 그것은 실제로 비교하려는 것에 달려 있습니다. 내 조언은 질문을 완전히 무시하고 String생성자를 사용하여 문자열 리터럴에서 문자열 객체를 만들지 않는 것 입니다.

참조
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


236
유형이 동일하면 === 더 빠르지 않습니다. 유형이 동일하지 않으면 ===는 변환을 시도하지 않기 때문에 더 빠릅니다.
Bill the Lizard

520
=== ==보다 느리지 않습니다. 둘 다 유형 검사를 수행하므로 === ==에 비해 추가 작업을 수행하지 않지만 유형 검사는 유형이 같지 않으면 === 더 빨리 종료되도록 할 수 있습니다.
Bill the Lizard

246
모든 == /! =를 === /! ==으로 바꾸면 js 파일의 크기가 커지고로드하는 데 시간이 더 걸립니다. :)
Marco Demaio

92
"... 복잡하고 기억에 남는 규칙은 ..."이제 그러한 진술을 통해 프로그래밍 할 때 안전하다고 느낄 수 있습니다 ...
Johan

47
크록 포드 (Crockford) : "일과성 결핍은 놀라운 일입니다." 비교 연산자 경보에서 소프트웨어를 개발하고 일시적인 결함이 발견되지 않거나 ==와 === 또는 파일 크기 /로드 시간 간의 속도 비교가 비교 연산자의 동작에 대한 전 이적 결정보다 우선시되는 경우 돌아가서 다시 시작해야 할 수도 있습니다.
jinglesthula

1144

==연산자 사용 ( Equality )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

===연산자 사용 ( Identity )

true === 1; //false
"2" === 2;  //false

항등 연산자 ==는 coercion 유형을 사용 하기 때문에 인터프리터가 암시 적으로 값을 변환하기 전에 값을 변환하려고 시도하기 때문입니다.

한편, 항등 연산자 ===는 유형 강제 변환을 수행 하지 않으므로 비교할 때 값을 변환하지 않으므로 ( 이 JS 벤치 마크 테스트 에 따라 ) 한 단계를 건너 뛰 므로 더 빠릅니다 .


9
@Software Monkey : 값 유형이 아님 (숫자, 부울, ...)
Philippe Leybaert

34
아무도 Javascript Equality Table을 언급하지 않았으므로 다음과 같습니다. dorey.github.io/JavaScript-Equality-Table
blaze

6
첫 번째 문장에서 'true'가 1로 변환되고 1이 true로 변환되지 않습니까?
Shadi Namrouti

2
"평등"과 "정체성"이라는 용어는 어디에서 유래합니까? 표준은 이러한 용어를 사용하지 않습니다. 그것은 호출 =="추상적 평등"과 호출 ==="엄격한 평등". ==모든 종류의 "평등"을 부여 한다는 것은 전 이적이지 않기 때문에 IMHO가 끔찍하지만 왜 떨리는가? 그래도 "identity"와 관련하여 더 많은 문제가 있습니다. 나는 그 용어가 "작동한다"고 말하지만 꽤 오해의 소지가 있다고 생각합니다. 그러나 진지하게 누가 "정체성"이라는 용어를 만들었습니까? 표준을 검색하여 찾을 수 없습니다.
Ray Toal

1
"정체성"은 매우 잘못된 단어입니다. 내가 사용했던 모든 언어의 정체성 비교 같은 개체의 수단 하나를 즉, 두 개의 참조 변수는 해당 엔티티하지 가리키는되지만 같은 엔티티.
Inigo

724

사이의 평등 비교의 재미있는 그림으로 표현 ==하고 ===.

출처 : http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

===JavaScript 평등 테스트에 사용하면 모든 것이 그대로입니다. 평가하기 전에 아무것도 변환되지 않습니다.

JS에서 ===의 평등 평가


var1 == var2

==JavaScript 평등 테스트에 사용할 때 약간의 펑키 변환이 발생합니다.

JS에서 ==의 평등 평가

이야기의 교훈:

에서 발생 ===하는 전환을 완전히 이해하지 않는 한 사용하십시오 ==.


3
@mfeineis = = 또는! = 대신 === 또는! ==을 의미합니다. 새로운 코더를 혼동하고 싶지 않아;)
katalin_2003

2
3 등호를 사용한 경험에서 문제가 발생할 수 있으므로 완전히 이해하지 않으면 피해야합니다. 두 개의 등식은 시간의 99 %가 실제로 유형이 같기를 원하지 않기 때문에 훨씬 더 나은 결과를 생성합니다 .
vsync

13
@vsync : 타입이 같지 않게 하려면 세 가지사용해야 합니다 !
SNag

7
한 가지 예외 : 안전하게 사용할 수 x == null있는지 확인하는 x것입니다 nullundefined.
Andy

1
@ user648026 : 문제는 vs 와의 동등 비교 에 관한 것입니다 . 어쨌든 대문자와 소문자는 같지 않으며 연산자 와 연산자 로 모두 반환 됩니다 . 또한, 키워드 , , , , 하나의 경우 JS에 존재하고, 상부 또는 혼합 된 경우에는 사용할 수 없다. =====false=====truefalseundefinednullInfinity
SNag

609

여기의 답변에서 나는 동등한 의미 가 무엇인지 전혀 읽지 못했습니다 . 어떤 사람들은 그것이 동일하고 같은 유형===의미 한다고 말하지만 실제로는 그렇지 않습니다. 실제로 두 피연산자가 동일한 객체를 참조 하거나 값 유형의 경우 동일한 값을 가짐을 의미 합니다.

다음 코드를 보자.

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

여기 동일합니다 :

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

또는:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

이 동작이 항상 명백한 것은 아닙니다. 평등하고 같은 유형의 것보다 더 많은 이야기가 있습니다.

규칙은 다음과 같습니다.

: 값 형식 (숫자)의 경우
a === b true를 반환하는 경우ab같은 값이 동일한 유형입니다

참조 유형의 경우 : 정확히 동일한 객체를 참조하고
a === btrueab참조하십시오.

: 문자열이 들어
a === b 있는 경우에 true를 돌려줍니다ab동일한 문자를 모두 문자열 및 포함


문자열 : 특별한 경우 ...

문자열은 값 유형이 아니지만 Javascript에서는 값 유형처럼 동작하므로 문자열의 문자가 동일하고 길이가 같은 경우 (제 3 규칙에 설명 된대로) "동일"합니다.

이제 흥미로워집니다.

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

그러나 이것은 어떻습니까? :

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

문자열이 값 유형처럼 동작한다고 생각 했습니까? 글쎄, 그것은 당신이 묻는 사람에 달려 있습니다 ...이 경우 a와 b는 같은 유형이 아닙니다. a유형 인 Object반면, b타입이다 string. String생성자를 사용하여 문자열 객체를 생성하면 대부분Object 문자열처럼 동작 하는 유형의 무언가가 생성 된다는 것을 기억하십시오 .


6
activa : 문자열이 리터럴 인 경우에만 문자열이 동일하다는 것을 분명히하고 싶습니다. new String ( "abc") === "abc"는 거짓입니다 (내 연구에 따르면).
Lawrence Dol 2016 년

3
new Number() == "0". Firefox에서도 :(function(){}) == "function () {\n}"
Thomas Eding

3
이유를 설명해 주셔서 감사합니다 new String("123") !== "123". 그들은 다른 유형입니다. 간단하면서도 혼란스러운.
styfle

21
String객체는 다른 객체 와 마찬가지로 문자열로 동작 합니다 . new String실제 문자열을 생성하지 않으므로 절대 사용해서는 안됩니다. 실제 문자열이며 문자열 리터럴로 만들거나 예를 들어 없이String 함수로 호출 할 수 있습니다 . newString(0); //"0", Real string, not an object
Esailija

6
그러나 자세한 경우 "=="연산자는 정확히 동일하게 동작합니다.
Yaron Levi

270

이 권고를 추가하겠습니다 :

확실하지 않은 경우 사양을 읽으십시오 !

ECMA-262는 JavaScript가 방언 인 스크립팅 언어의 사양입니다. 물론 실제로 가장 중요한 브라우저의 작동 방식은 무언가를 어떻게 처리해야하는지에 대한 난해한 정의보다 중요합니다. 그러나 왜 new String ( "a")! == "a" 인지 이해하는 것이 도움이됩니다 .

이 질문을 명확히하기 위해 사양을 읽는 방법을 설명하겠습니다. 나는이 아주 오래된 주제에서 아무도 그 이상한 효과에 대한 답을 얻지 못했다는 것을 알았습니다. 따라서 사양을 읽을 수 있다면 이것은 직업에 큰 도움이 될 것입니다. 습득 한 기술입니다. 계속하겠습니다.

===에 대한 PDF 파일을 검색하면 사양의 56 페이지로 이동합니다 : 11.9.4. Strict Equals Operator (===) 이며 사양을 검토 한 후 다음을 발견했습니다.

11.9.6 엄격한 평등 비교 알고리즘
x와 y가 값인 x === y 비교는 true 또는 false를 생성 합니다 . 이러한 비교는 다음과 같이 수행됩니다.
  1. Type (x)가 Type (y)와 다른 경우 false를 반환 합니다.
  2. Type (x)가 Undefined 이면 true를 반환 합니다 .
  3. Type (x)가 Null 이면 true를 반환 합니다 .
  4. Type (x)가 숫자가 아니면 11 단계로 이동하십시오.
  5. x가 NaN 이면 false를 리턴하십시오 .
  y가 NaN 인 경우 false를 반환 합니다.
  7. x가 y와 같은 숫자 값 이면 true를 반환 합니다 .
  8. x가 +0이고 y가 −0 이면 true를 반환 합니다 .
  9. x가 -0이고 y가 +0 이면 true를 반환 합니다 .
  10. false를 리턴하십시오 .
  11. Type (x)가 String 이면 x와 y가 정확히 동일한 문자 시퀀스 (해당 위치의 동일한 길이와 동일한 문자) 이면 true 를 반환 합니다 . 그렇지 않으면 false를 반환하십시오 .
  12. Type (x)가 부울 인 경우 x와 y가 모두 true 이거나 모두 false 이면 true를 반환 합니다 . 그렇지 않으면 false를 반환하십시오 .   13. 반환
x와 y가 같은 객체를 참조하거나 서로 연결된 객체를 참조하는 경우 (13.1.2 참조) 그렇지 않으면 false를 반환하십시오 .

흥미로운 단계는 11 단계입니다. 예, 문자열은 값 유형으로 처리됩니다. 그러나 이것은 왜 새로운 String ( "a")! == "a" 인지 설명하지 않습니다 . ECMA-262를 준수하지 않는 브라우저가 있습니까?

그렇게 빠르지 않습니다!

피연산자의 유형을 확인하십시오. typeof () 로 감싸서 직접 사용해보십시오 . 나는 그 찾아 새로운 문자열 ( "A"는) 객체이며, 1 단계는 사용됩니다 반환 거짓 종류가 다른 경우.

new String ( "a") 이 문자열을 반환하지 않는 이유가 궁금하다면 사양을 읽는 연습은 어떻습니까? 즐기세요!


Aidiakapi는 아래의 주석에서 이것을 썼습니다 :

사양에서

11.2.2 새로운 연산자 :

Type (constructor)이 Object가 아닌 경우 TypeError 예외를 발생시킵니다.

즉, String이 Object 유형이 아니면 new 연산자와 함께 사용할 수 없습니다.

new는 항상 String 생성자에 대해서도 Object를 반환합니다 . 그리고 아아! 문자열의 값 의미 (11 단계 참조)가 손실됩니다.

그리고 이것은 마지막으로 다음을 의미합니다 : new String ( "a")! == "a" .


Type (x)의 결과는 typeof?와 같음을 암시합니다.
Dfr

@nalply 나는 new String('x')원시 래퍼 객체를 사용하는 와일드 코드를 본 적이 없으며 특히 요즘에는 그럴만 한 이유가 없다고 생각하기 때문에 와의 동작에 대한 불안을 정확하게 이해 하지 못합니다. 그런 코드를 본 적이 있습니까?
Andy

@Andy 문제는 악의적이거나 부주의 한 타사 코드이므로 아무도 사용하지 않는다고 가정 할 수 없습니다 new String().
nalply

느슨하면 === 방법을 찾을 수 있습니다. 악의적 인 경우 new String()아마도 가장 걱정할 것입니다. 나는 이론의 관심사를 이해하지만 다시 실제 사례가 있습니까? 나에게 그것은 누군가가 undefined다른 가치로 설정할 수 있었던 오래된 불안과 같습니다 .
Andy

이 정보를 어디서 얻었는지 모르겠지만 2 단계에서 비교 알고리즘이 잘못되었습니다. "7.2.15 엄격한 평등 비교"섹션은 먼저 유형이 동일한 지 여부를 확인합니다 (예인 경우 숫자인지 여부). 그렇지 않으면 "7.2.12 SameValueNonNumber (x, y)"섹션이 사용됩니다.
Rusty Core

101

PHP와 JavaScript에서 엄격한 항등 연산자입니다. 즉, 유형과 값을 모두 비교합니다.


10
@David : 맞습니다. 그렇기 때문에이 답변이 정확하지 않거나 잘못된 것입니다.
Philippe Leybaert

7
@David var a = {}, b = {}; a == b는 false를 반환합니다.
nyuszika7 시간

6
예 : 유형과 값이 같은 두 개의 다른 객체가 false를 비교합니다. 즉,이 답변은 잘못되었습니다. 왜 공감 율이 50입니까?
Alexis

4
나는 이것이 오래되었다는 것을 알고 있지만이 대답이 여전히 정확한 이유를 분명히하는 것은 예제 var a = {}, b = {};에서 모두 ab실제로는 두 가지이지만 기술적으로 말하면 동일한 값 이 아니기 때문 입니다. 그것들은 다른 인스턴스입니다. 인스턴스 비교는 기본 요소를 비교하는 것과 다르게 작동합니다. 아마도이 혼란에 추가됩니다. 기본 데이터 유형의 인스턴스 버전을 사용하는 경우 유사한 비교 동작이 표시됩니다. 예를 들어 new String('asdf')또는 new Number(5). 예 : new Number(5) == new Number(5)값이 같더라도 거짓입니다.
Norman Breau

1
우리는 객체에 대한 참조가 실제로 메모리 슬롯에 대한 포인터이기 때문에 값 유형이라는 것을 잊습니다. 객체 비교는 "객체의 값"을 비교하는 것이 아니라 두 포인터가 동일한 지 여부는 동일한 메모리 슬롯을 참조한다는 의미입니다. "==="연산자가 "메모리의 객체에 대한 유형, 값 및 참조가 동일한 경우"라고 말해야하기 때문에 이는 유형 비교에서 매우 미묘한 차이입니다.
Stokely

101

다음 과 같은 코드를 사용하여 Firefox에서 Firebug로 이것을 테스트 했습니다.

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

내 결과 (각 5 회 테스트 및 평균) :

==: 115.2
===: 114.4

따라서 작은 차이 (100000 회 이상 반복됨)는 무시할 만하다고 말하고 싶습니다. 성능 해야 할 이유 가 아닙니다=== . 유형 안전 (자바 스크립트에서 얻을 수있는만큼 안전)과 코드 품질이 좋습니다.


3
타입 안전성 이상의 논리적 인 정확성을 원합니다. 때로는 ==동의하지 않을 때 진실이되기를 원합니다 .
rpjohnst

4
이제 ==연산자에 대한 실제 유형 강제가있을 때이를 어떻게 비교 합니까? 이때 성능이 향상됩니다.
휴 버트 OG

2
유형 불평등을 더 빨리 점검하는 전술 한 이유로 올바르게 테스트했을 때의 주요 차이점. jsfiddle.net/4jhuxkb2
Doug Morrow

console.time ()을 사용하여 단일 브라우저 (시장 점유율이 약 5 % 인 단일 브라우저)에서 단일 테스트가 아닌 유형 / 강제를 사용하지 않는 테스트 (전체 이유)로 이와 같은 성능을 초당 측정합니다. 속도가 느려집니다). 이것은 완전히 의미없는 테스트입니다. 당신은 성능을 사용하는 이유는 아니라고 올바른지 ===이상이 ==있지만 성능은 본질적으로 동일하다고 잘못이며,이 테스트는 것을 증명 생각하는 것, 다른 많은 사람들이 동의하고 있음을 나에게 완전히 터무니없는 것입니다.
Stephen M Irving

97

JavaScript에서는 동일한 값과 유형을 의미합니다.

예를 들어

4 == "4" // will return true

그러나

4 === "4" // will return false 

87

=== 연산자는, 엄밀한 비교 연산자라고 않는 로부터 다를 == 연산자.

2 가지 a와 b를 취하겠습니다.

들어 "는 ==의 B" 로 진정한 a와 b의 필요성을 평가하기 위해 같은 값 .

의 경우 "는 === B" a와 b는해야합니다 같은 값 또한 동일한 유형 이 true로 평가하기 위해.

다음 예제를 보자

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

요약하면 ; 원하지 않는 상황에서 == 연산자를 사용하면 true로 평가되므로 === 연산자를 사용하는 것이 더 안전합니다.

90 % 사용 시나리오에서는 어떤 것을 사용하든 관계가 없지만 언젠가 예기치 않은 동작이 발생할 때의 차이점을 아는 것이 편리합니다.


82

==그렇게 예측할 수 없습니까?

빈 문자열 ""을 숫자 0과 비교하면 무엇을 얻 0습니까?

true

그렇습니다 ==. 빈 문자열 에 따라 맞으며 숫자 0은 같은 시간입니다.

그리고 거기서 끝나지 않습니다. 여기 또 다른 것이 있습니다.

'0' == false // true

배열은 정말 이상합니다.

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

그런 다음 줄이 이상해

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

더 나 빠진다 :

언제 같지 않습니까?

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

다시 말해 보겠습니다.

(A == B) && (B == C) // true
(A == C) // **FALSE**

그리고 이것은 당신이 프리미티브로 얻는 미친 것들입니다.

==객체와 함께 사용할 때 완전히 새로운 수준의 미친 것 입니다.

이 시점에서 아마도 궁금 할 것입니다 ...

왜 이런 일이 발생합니까?

"triple equals"( ===) 와 달리 두 값이 같은지 확인하기 때문입니다.

==다른 것들전체 무리를 수행합니다 .

함수에 대한 특수 처리, 널에 대한 특수 처리, 정의되지 않은 문자열이 있으며 이름을 지정합니다.

꽤 별나다.

실제로, 어떤 기능을 수행하는 함수를 작성하려고하면 ==다음과 같이 보일 것입니다.

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // 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 y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    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;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

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

이것이 무엇을 의미합니까?

==복잡하다는 의미 입니다.

복잡하기 때문에 사용할 때 어떤 일이 일어날 지 알기가 어렵습니다.

이는 버그로 끝날 수 있음을 의미합니다.

이야기의 교훈은 ...

인생을 덜 복잡하게 만드십시오.

===대신에 사용하십시오 ==.

끝.


당신의 looseEqual잘못입니다. Function == Function.toString()사실이지만 looseEqual(Function, Function.toString())거짓입니다. 처음에 함수를 필터링하는 이유를 잘 모르겠습니다.
Oriol

@Oriol 당신 말이 맞아, 나는 그것을 설명하기 위해 코드를 업데이트했다. FYI는 내 테스트를 기반으로 "기능"에 대한 필터를 제거하기에 충분하지 않았으며 대신 "기능"이 완전히 다르게 처리되어야했다.
Luis Perez

주의 사양이 다르게 치료 기능을하지 않습니다, 그들은 단지 개체입니다. 문제 typeof x === "object"는 객체인지 확인하는 데 의존 하지만`typeof는 null이 아닌 프리미티브에만 작동합니다. 값이 객체인지 확인하는 올바른 방법 목록에
Oriol

함수와 객체를 동일하게 처리하려고 시도했지만 결과가 잘못되었습니다. 예를 들어 함수가 객체처럼 취급 된 경우 함수와 일치하는 valueOf () 또는 toString () 함수를 구현하는 객체와 함수를 비교하면 실제로는 전달되지 않습니다. 예 : (function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}-모든 테스트를 실행하는이 JS Fiddle을 확인하십시오. jsfiddle.net/luisperezphd/7k6gcn6g (1,225 개의 테스트 순열이 있음)
Luis Perez

1
당신이 옳고 훌륭한 관찰입니다. 이것은 ==결과를 예측하는 것을 매우 어렵게 만드는 많은 것을 강조하는 주요 요점을 강조하는 반면 권장되는 선택 ===의 주요 이유 중 하나 인 훨씬 더 간단하고 예측 가능 ===합니다. (당신의 요점을 언급 한 답변에 메모를 추가하겠습니다)
Luis Perez

81

===같은 변의 유형 이 같은지 확인 합니다 .


예:

'1' === 1 // will return "false" because `string` is not a `number`

일반적인 예 :

0 == ''  // will be "true", but it's very common to want this check to be "false"

또 다른 일반적인 예 :

null == undefined // returns "true", but in most cases a distinction is necessary

많은 시간이 지정되지 않은 값이 하나 인 경우 당신은 상관하지 않기 때문에 검사가 편리 할 것 undefined, null, 0 또는""


7
또한,'string' !== 'number'
호머

71

엄격한 평등을위한 자바 스크립트 실행 흐름도 / 비교 '==='

자바 스크립트의 엄격한 평등

엄격하지 않은 동등성 / 비교를위한 자바 스크립트 실행 흐름도 '=='

자바 스크립트 비 균등


string화살표가 큰 회색 상자를 가리키는 이유를 이해하지 못합니다 . 인터럽터가 문자열을 숫자로 캐스팅한다는 것을 의미합니까?
vsync

@vsync 회색 상자 안의 문자열 옵션을 가리 킵니다. 즉 문자열-> # || NaN. Javascript는 유형 스크립트 언어가 아닙니다. 기본적으로 모든 유형의 변수를 가질 수 있습니다. 따라서 그것은 회색 상자를 가리 킵니다.
Samar Panda

나는 string타입과 비교되어야하기 때문에 캐스팅 목적인지 여부를 간단히 물었습니다 number. 인터럽터는 문자열과 비교해야 할 문자열을보고 그에 따라 문자열을 캐스팅합니까?
vsync

1
큰 회색 상자는 ToNumber다른 유형이 주어지면 반환되는 것이므로 문자열이 주어지면 마지막 옵션 만 선택하고 숫자로 변환합니다. ==용도 ToNumber만의 경우 string == numberboolean == anything(만 위에서 string/ boolean). 이 방법은 ==변환하지 않습니다 undefined또는 null그들은 회색 상자에있다하더라도. (하나의 조합의 경우 undefinednull또는 두 가지 모두, ==항상 돌아갑니다 true., 값이 중요하지 않습니다 왼쪽 또는 오른쪽에 있는지, 또한 ==(와 ===같은 결과를 반환합니다).)
user2033427

55

자바 스크립트를 === == .

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

54

강제 변환 유형이 없는 평등을 의미 합니다. 강제 변환 유형은 JavaScript가 다른 데이터 유형을 문자열 데이터 유형으로 자동 변환하지 않음을 의미합니다.

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 

48

일반적인 스크립트에서는 성능 차이가 없습니다. 천 "==="이 천 KB보다 1KB 무겁다는 사실이 더 중요 할 수 있습니다. ") JavaScript 프로파일 러 는 귀하의 경우에 성능 차이가 있는지 알려줄 수 있습니다.

그러나 개인적으로 JSLint가 제안한대로 할 것입니다. 이 권장 사항은 성능 문제가 아니라 유형 강제 변환 수단 ('\t\r\n' == 0)이 사실 이기 때문 입니다.


4
항상 사실은 아닙니다. gzip 압축을 사용하면 그 차이는 거의 무시할 수 있습니다.
Daniel X Moore

1
동의하지만, 천 "==="은 10 만 개의 코드 라인을 의미합니다. 따라서 1kb 더 많거나 적습니다 ...;)
Jonny

f 크기에 관심이 있다면 모든 ==를 ===로 바꾸고,

46

등호 비교 연산자 ==는 혼동되므로 피해야합니다.

이 경우 필요가 그것으로 살고, 다음 3 가지를 기억 :

  1. 전 이적이지 않습니다 : (a == b)(b == c)(a == c)
  2. 그것은 그것의 부정에 상호 배타적입니다 : (A == B)(A = B!) 항상 모든 a와 b로, 반대 부울 값을 누릅니다.
  3. 의심이가는 경우 다음 진리표를 가슴에 새기십시오.

JAVASCRIPT의 등가 조작자 트루 테이블

  • 표의 각 행은 서로 "동일한"3 개의 값 집합으로, 그 중 2 개의 값은 등호 == 부호 *를 사용하여 동일합니다.

** STRANGE : 첫 번째 열의 두 값은 그런 의미에서 동일하지 않습니다. **

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.

39

사용 중 두 작업간에 성능 차이가 없을 것입니다. 두 매개 변수가 이미 동일한 유형이므로 유형 변환이 수행되지 않습니다. 두 작업 모두 유형 비교와 값 비교가 있습니다.


38

예! 상관 있지.

===자바 스크립트 연산자 검사 유형뿐만 아니라 가치 로서 ==오퍼레이터 단지 확인 값 (필요한 경우 형 변환을 수행) .

여기에 이미지 설명을 입력하십시오

쉽게 테스트 할 수 있습니다. HTML 파일에 다음 코드를 붙여 넣고 브라우저에서 엽니 다

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

경고 메시지에 ' 거짓 '이 표시됩니다. 이제 수정 onPageLoad()에 방법을 alert(x == 5);얻을 것이다 당신이 진정한 .


33

=== 연산자는 변수의 유형뿐만 아니라 값이 같은지 확인합니다.

== 연산자는 변수의 값이 같은지 확인합니다.


32

엄격한 검사 테스트입니다.

0과 false와 null 사이를 검사하는 경우 특히 좋습니다.

예를 들어 다음과 같은 경우

$a = 0;

그때:

$a==0; 
$a==NULL;
$a==false;

모두 true를 반환하며이를 원하지 않을 수 있습니다. 배열의 0 번째 인덱스를 반환하거나 실패시 false를 반환 할 수있는 함수가 있다고 가정합니다. "=="false로 확인하면 혼란스러운 결과를 얻을 수 있습니다.

위와 동일하지만 엄격한 테스트를 사용하십시오.

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

3
JavaScript에서 이것은 완전히 잘못되고 잘못되었습니다. 0 != null. -1
Ry-

31

JSLint는 때로는 비현실적인 이유를 제공합니다. 유형이 이미 동일한 ===것처럼 정확히 동일한 성능을 갖습니다 ==.

유형이 동일하지 않은 경우에만 더 빠르며,이 경우 유형 변환을 시도하지 않고 직접 false를 리턴합니다.

따라서 IMHO, JSLint는 새 코드를 작성하는 데 사용될 수 있지만 모든 비용으로 쓸모없는 과다 최적화를 피해야합니다.

즉, 문자열 만 될 수 있다는 사실을 알 때 와 같이 검사에서 변경 ==해야 할 이유가 없습니다 .===if (a == 'test')

많은 코드를 수정하면 개발자와 검토 자의 시간을 낭비하고 아무것도 달성하지 못합니다.


30

간단히

==의미 비교 연산자와 함께를 type conversion

&

===의미 비교 피연산자 사이 없이를 type conversion

javaScript에서 유형 변환은 javaScript가 다른 모든 데이터 유형을 문자열 데이터 유형으로 자동 변환 함을 의미합니다.

예를 들면 다음과 같습니다.

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

26

간단한 예는

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

25

위에서 언급 한 두 가지 답변은 ==는 평등을 의미하고 ===는 정체성을 의미합니다. 불행히도이 문장은 틀렸다.

==의 두 피연산자가 모두 객체이면 동일한 객체인지 확인하기 위해 비교됩니다. 두 피연산자가 모두 동일한 객체를 가리키는 경우 등호 연산자는 true를 반환합니다. 그렇지 않으면 둘이 동일하지 않습니다.

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

위의 코드에서 a와 b는 같은 객체가 아니기 때문에 ==와 === 모두 false가됩니다.

즉, ==의 두 피연산자가 모두 객체 인 경우 ==는 ===와 동일하게 동작하며 이는 또한 동일성을 의미합니다. 이 두 연산자의 근본적인 차이점은 형식 변환에 관한 것입니다. == 동일성을 검사하기 전에 변환이 있지만 ===는 변환하지 않습니다.


24

경험상, 나는 일반적으로 ===대신 ==( !==대신 !=)을 사용합니다.

이유는 위의 답변에 설명되어 있으며 Douglas Crockford는 이에 대해 분명합니다 ( JavaScript : The Good Parts ).

그러나 하나의 예외가 있습니다 : == null'null 또는 undefined'를 확인하는 효율적인 방법입니다.

if( value == null ){
    // value is either null or undefined
}

예를 들어, jQuery 1.9.1은이 패턴을 43 번 사용하고 JSHint 구문 검사기eqnull이러한 이유로 편안한 옵션을 제공합니다 .

로부터 의 jQuery 스타일 가이드 :

엄격한 평등 검사 (===)는 ==에 유리하게 사용해야합니다. null을 통해 undefined 및 null을 검사 할 때는 예외입니다.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

22

JavaScript는 많은 암시 적 변환을 의미하기 때문에 문제가 발생하기 쉽다는 것이 문제입니다.

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

곧 문제가 될 것입니다. 암시 적 변환이 "악"인 이유에 대한 가장 좋은 샘플은 MFC / C ++ 의이 코드에서 가져올 수 있는데, 이는 포인터 typedef 유형 인 CString에서 HANDLE 로의 암시 적 변환으로 인해 실제로 컴파일됩니다.

CString x;
delete x;

분명히 런타임 중에 매우 정의되지 않은 일을하는 것은 ...

C ++ 및 STL 에서 암시 적 변환을위한 Google은 이에 대한 몇 가지 주장을 얻었습니다 ...


2
0 == null거짓입니다.
Garrett


21

평등 비교 :

운영자 ==

두 피연산자가 모두 같으면 true를 반환합니다. 피연산자는 비교하기 전에 동일한 유형으로 변환됩니다.

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

평등 및 유형 비교 :

운영자 ===

두 피연산자가 같고 같은 유형 인 경우 true를 리턴합니다. 비하인드 유형 변환이 없기 때문에이 방법을 비교하면 일반적으로 더 안전합니다.

>>> 1 === '1'
false
>>> 1 === 1
true


20

null과 undefined는 무의미하다.

var a;
var b = null;

다음 ab값이 없습니다. 반면 0, false 및 ''는 모두 값입니다. 이 모든 것 사이에서 공통적 인 한 가지는 그것들이 모두 잘못된 값이라는 것입니다. 즉, 모두 잘못된 조건을 만족 시킵니다.

따라서 0, false 및 ''은 함께 하위 그룹을 형성합니다. 반면에 null & undefined는 두 번째 하위 그룹을 형성합니다. 아래 이미지에서 비교를 확인하십시오. null과 undefined는 같습니다. 다른 세 사람은 서로 같습니다. 그러나 이들은 모두 JavaScript에서 잘못된 조건으로 취급됩니다.

여기에 이미지 설명을 입력하십시오

이것은 {}, 배열 등과 같은 모든 객체와 동일하며, 비어 있지 않은 문자열 및 부울 true는 모두 진실한 조건입니다. 그러나 그들은 모두 평등하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.