JavaScript에서 ( "foo"=== new String ( "foo"))가 false로 평가되는 이유는 무엇입니까?


98

문자열 값을 비교할 때 항상 === (삼중 같음, 엄격한 비교) 사용을 시작하려고했지만 이제는

"foo" === new String("foo")

거짓이며 다음과 동일합니다.

var f = "foo", g = new String("foo");
f === g; // false

물론이야:

f == g; // true

따라서 문자열 비교를 위해 항상 ==를 사용하거나 비교하기 전에 항상 변수를 문자열로 변환하는 것이 좋습니다.


6
어쩌면 때문에 foo순수 문자열입니다 및 new String("foo")개체의 문자열입니다
다닐 발렌테


6
new String사용하는 대신 (완전히 무의미한) 문자열을 생성하지 않는 것이 좋습니다==
Esailija

2
왜 누구나 new String("foo")처음에 Javascript 와 같은 구조를 사용하고 싶 습니까? 나는 ... jQuery를, 즉 코드에서 이러한 코드를 본 적이
로버트 Koritnik

2
String(obj)"string"매개 변수를 받으면 박스형 문자열을 기본 형식으로 변환하는 데 사용할 수 있습니다 . ("foo" === String(new String("foo"))) === true
OrangeDog

답변:


126

"foo"문자열 프리미티브 입니다. (이 개념은 C # 또는 Java에 존재하지 않습니다)

new String("foo") 박스형 문자열 객체입니다.

===연산자는 프리미티브와 개체에 다르게 작동합니다 .
(동일한 유형의) 프리미티브를 비교할 때 ===둘 다 동일한 값을 가지고 있으면 true를 반환합니다.

객체를 비교할 때 ===동일한 객체를 참조하는 경우에만 true를 반환합니다 (참조로 비교). 따라서 new String("a") !== new String("a").

귀하의 경우 ===피연산자가 다른 유형이기 때문에 false를 반환합니다 (하나는 원시이고 다른 하나는 객체입니다).


프리미티브는 전혀 객체가 아닙니다. 운영자는 반환하지 않습니다 기본 요소.
typeof"object"

(객체로 사용하는) 기본 속성에 액세스하려고 할 때 Javascript 언어는 매번 새 객체를 생성하여 객체에 상자를 넣습니다. 이것은 사양에 설명되어 있습니다.

이것이 프리미티브에 속성을 넣을 수없는 이유입니다.

var x = "a";
x.property = 2;
alert(x.property) //undefined

당신이 쓸 때마다 x.property하는 다른 박스 String객체가 만들어집니다.


33
+1 typeof "foo"; // "string",typeof new String("foo"); // "object"
Sampson

1
흥미롭게도 문자열이 JS의 객체라고 생각했습니다.
Cameron Martin

1
@Sarfraz : 거의 모든 것. null및 에 대해 잊지 마십시오 undefined.

2
if( Object(a) !== a ) { //it's a primitive }
Esailija 2012-06-08

1
자바는 프리미티브를해야합니까 / 닷넷하지
마르셀 드 선

34

사용하여 ===,

  • Object는 자신에 대한 다른 참조를 제외하고는 절대로 동일하지 않습니다.

  • 프리미티브는 유형과 값이 같으면 다른 프리미티브와 비교할 때 동일합니다.


3
new String("foo") === new String("foo")is false:-P
Rocket Hazmat

10

여기서 그 new단어는 범죄자입니다 ( 평소처럼 말하겠습니까) ...

를 사용할 때 객체new 작업에 대한 욕구를 명시 적으로 표현합니다 . 당신에게는 놀라 울 수도 있지만 이것은 :

var x = new String('foo');
var y = new String('foo');
x === y; 

... 당신에게 강력한 것을 줄 것 false입니다. 간단합니다. 비교는 객체의 내부가 아니라 객체의 참조입니다. 그리고 물론 두 개의 다른 객체가 만들어 졌기 때문에 동일하지 않습니다.

아마도 사용하고 싶은 것은 변환입니다 .

var x = String('foo');
var y = String('foo');
x === y;

... 그리고 예상 true대로 결과적으로 당신은 foos영원히 평등하게 기뻐하고 번영 할 수 있습니다. )


2
이것을 사용하는 것에 대한 빠른 질문. 'new'키워드없이 String (생성자?)을 호출하고 있습니다. 이것은 String 생성자 내에 할당 된 속성으로 범위를 오염시킬 것이라는 의미가 아닙니까? 아니면 생성자가 네이티브 코드이기 때문에 발생하지 않습니까? 즉, String 함수에 "this.a = 1;"이 포함되어 있다고 가정합니다. - 그 함수 / 객체가 이제 속성 A = 1. 것이다 의미
마이클 버틀러

각 '복싱 생성자'함수가 먼저 컨텍스트를 확인한다고 가정합니다 (확실히 말할 수는 없음). '새로운 것'(즉, 프로토 타입 객체)이 아닌 경우 즉시 변환 방법으로 전환합니다. toString()예를 들어 메서드 가 될 문자열의 경우 .
raina77ow


2

node.js REPL (설치된 경우 명령 줄의 "node")에서 :

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.