변수 === 정의되지 않은 변수 대 typeof 변수 ===“정의되지 않음”


300

jQuery를 핵심 스타일 가이드 라인이 변수가 정의되어 있는지 여부를 확인하는 두 가지 방법을 제안한다.

  • 전역 변수 : typeof variable === "undefined"
  • 지역 변수 : variable === undefined
  • 속성 : object.prop === undefined

jQuery가 전역 변수에 대해 하나의 접근법을 사용하고 로컬 및 특성에 대해 다른 접근법을 사용하는 이유는 무엇입니까?


왜 JQuery가 두 가지 접근 방식을 모두 사용하는지에 대한 질문에 대답 할 수는 없지만 Javascript에는이 두 가지가 미묘하게 다르다는 흥미로운 특징이 있습니다. 그것은해야하지없이 대부분의 시간 (즉, 코드가 제정신 인 경우),하지만이 차이는 그럼에도 불구하고 있습니다 : 쓰기까지 여기를 참조하십시오 - wtfjs.com/2010/02/15/undefined-is-mutable
Spudley

2
@Struppi가 지적했듯이 jQuery의 가장 바깥 쪽 함수에는 undefined라는 인수가 있습니다. jQuery 내 foo === undefined에서 전역 코드 (window.undefined) 대신 undefined의 로컬 사본을 검사합니다.이 코드는 미친 코드로 수정되었을 수 있습니다. undefined가 변경 가능하다는 사실은 분명히 주목할 가치가 있으며 나는 당신이 기쁘다. (+1)
Patrick McElhaney

1
이 기사의 현재 링크는 wtfjs.com/wtfs/2010-02-15-undefined-is-mutable
Enigment

답변:


366

선언되지 않은 변수의 typeof foo경우 문자열 리터럴을 반환 "undefined"하지만 ID 확인 foo === undefined"foo is not defined" 오류를 트리거합니다 .

(로컬 변수의 어딘가에 선언), 이러한 오류는, 따라서 신원 확인을 발생하지 않을 것이다.


3
@goreSplatter 지금 삭제할 수 없습니다. :-) 선택하기 어려웠지만 질문이 표현되는 방식에 따라이 답변이 더 적합합니다. 정의되지 않은 작동 방식에 관심이있는 사람은 (나와 같이) 다른 답변, 특히 @Tim도 살펴보십시오.
Patrick McElhaney

4
따옴표 ( typeof foo; // -> "undefined")를 추가 하여 기본 값이 아니라 문자열임을 강조합니다 undefined.
c24w

117

나는 typeof foo === "undefined"모든 곳 에서 사용하는 것을 고수했다 . 결코 잘못 될 수 없습니다.

jQuery가 두 가지 다른 메소드를 권장하는 이유 undefined는 jQuery 코드가 존재하는 함수 내에서 자신의 변수 를 정의하기 때문에 해당 함수 내 undefined에서 외부에서 변경하는 것이 안전하다는 것입니다. 또한 어딘가에 누군가가 두 가지 다른 접근법을 벤치마킹하고 foo === undefined그것이 더 빠르다 는 것을 알았 으므로 그것이 갈 길이라고 결정했습니다. [업데이트 : 의견에서 언급 한 바와 같이, 비교 undefined도 약간 짧아 고려할 수 있습니다.] 그러나 실제 상황에서의 이득은 전혀 중요하지 않을 것입니다. 비교할 호스트 개체의 속성을 평가하면 오류가 발생할 수 있지만typeof 확인하지 않습니다.

예를 들어, 다음은 IE에서 XML 구문 분석을 위해 사용됩니다.

var x = new ActiveXObject("Microsoft.XMLDOM");

loadXML메소드가 안전하게 있는지 확인하려면 다음을 수행하십시오 .

typeof x.loadXML === "undefined"; // Returns false

반면에 :

x.loadXML === undefined; // Throws an error

최신 정보

typeof내가 언급하지 않은 확인 의 또 다른 장점은 선언되지 않은 변수와도 작동하며 확인되지 않은 변수 foo === undefined와 실제로 작동한다는 것 ReferenceError입니다. 상기시켜 주신 @LinusKleen에게 감사드립니다. 예를 들면 다음과 같습니다.

typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError

결론 : 항상 typeof확인을 사용 하십시오.


10
고마워 팀. 성능에 대한 당신의 요점은 합리적입니다. jQuery 팀은 파일 크기에 미치는 영향에 대해 더 우려하고 있습니다. foo === undefined을 최소화하면 아마도 같은 것일 수 f===u있지만 typeof foo === "undefined"로만 줄일 수 typeof f==="undefined"있습니다.
Patrick McElhaney

1
당신은 var u = "undefined"그것을 정의 하고 줄일 수 있습니다 typeof f==u.
Tim Down

5
좋은 지적이지만 typeof선언되지 않은 변수 에 대한 안전이 이점 인지 확실하지 않습니다 . 그것이 오타를 더 쉽게 지나칠 수있게하고 실제로 선언되지 않은 변수의 유형을 확인하고 싶을 때 볼 수 없습니다.
David Tang

2
@ Box9 : 다른 라이브러리가 있는지 확인하기 위해 라이브러리에서 사용한다고 상상할 수 있습니다.
Tim Down

2
@ jontro : JSLint를 사용하지 않는 이유 중 하나입니다.
Tim Down

29

type-variant :를 사용하는 또 다른 이유는 undefined재정의 될 수 있습니다.

undefined = "foo";
var variable = "foo";
if (variable === undefined)
  console.log("eh, what?!");

그 결과 typeof variable 는 불가능합니다.

업데이트 : ES5의 경우에는 그렇지 않습니다. 전역 undefined은 구성 불가능하고 쓸 수없는 속성입니다.

15.1.1 전역 객체의 값 속성
[...]
15.1.1.3 undefined
undefined이 정의되어 있지 않습니다 (8.1 참조). 이 속성의 속성은
{[[Writable]] : false, [[Enumerable]] : false, [[Configurable]] : false}입니다.

그러나 여전히 로컬 변수에 의해 음영 처리 될 수 있습니다.

(function() {
  var undefined = "foo";
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})()

또는 매개 변수 :

(function(undefined) {
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})("foo")

17
ES5에서 재정의 할 수 없습니다.
Ry-

6
전역 undefined속성은 ES5에서 재정의 할 수 없지만 여전히 로컬 변수로 음영 처리 될 수 있습니다. void 0더 짧고 안전합니다.
Oriol

7

하기 때문에 undefined항상 선언되지 않지만, jQuery를 선언 undefined의 주요 기능에. 따라서 undefined내부적으로 안전한 가치 를 사용 하지만 외부에서는 typeof안전한 스타일을 사용합니다 .



1

지역 변수의 localVar === undefined경우 지역 범위 내에서 정의되어 있거나 지역으로 간주되지 않기 때문에 점검 이 작동합니다.

로컬이 아니며 어디에도 정의되지 않은 변수의 경우 검사에서 someVar === undefined예외가 발생합니다. 잡히지 않은 ReferenceError : j가 정의되지 않았습니다.

여기 내가 위에서 말하는 것을 분명히하는 코드가 있습니다. 추가 명확성을 위해 인라인 주석에주의하십시오 .

function f (x) {
    if (x === undefined) console.log('x is undefined [x === undefined].');
    else console.log('x is not undefined [x === undefined.]');

    if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
    else console.log('x is not undefined [typeof(x) === \'undefined\'].');

    // This will throw exception because what the hell is j? It is nowhere to be found.
    try
    {
        if (j === undefined) console.log('j is undefined [j === undefined].');
        else console.log('j is not undefined [j === undefined].');
    }
    catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}

    // However this will not throw exception
    if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
    else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};

위의 코드를 다음과 같이 호출하면

f();

결과는 다음과 같습니다.

x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

위와 같은 코드를 다음과 같이 호출하면 (실제로 값이 있음)

f(null); 
f(1);

출력은 다음과 같습니다.

x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

다음과 같이 검사를 수행하면 다음과 같이 typeof x === 'undefined'본질적으로 묻습니다 . 소스 코드에 변수 x가 존재 하는지 (정의되어 있는지) 확인하십시오 . (더 많거나 적음). C # 또는 Java를 알고있는 경우이 유형의 검사는 존재하지 않으면 컴파일되지 않으므로 수행되지 않습니다.

<== 피들 미 ==>


1

요약:

전역 범위에서 변수가 선언되지 않았거나 값이 있으면 실제로 true를 반환하려고합니다 undefined.

var globalVar1;

// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);

// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);

전역 범위에서는 변수가 선언되었는지 100 % 확신 할 수 없기 때문에 referenceError가 발생할 수 있습니다. typeof알 수없는 변수 에서 연산자를 사용할 때 변수가 선언되지 않은 경우이 문제가 발생하지 않습니다.

var globalVar1;

console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');

이것은 변수가 선언되지 않았거나 현재 원하는 값 을 보유하고있을 때 typeof연산자가 문자열을 반환 하기 때문입니다 .undefinedundefined


  • 로컬 변수를 사용하면이 변수가 존재한다는 것을 미리 알고 있기 때문에이 문제가 없습니다. 변수가 존재하면 간단히 해당 함수를 살펴볼 수 있습니다.
  • 객체 속성을 사용하면 존재하지 않는 객체 속성을 조회하려고 할 때 값도 얻으므로이 문제가 발생하지 않습니다 undefined

var obj = {};

console.log(obj.myProp === undefined);


-5

typeof a === 'undefined'다음 빠른 a === 'undefined'노드 v6.9.1에 약 2 배.


3
입력 한 내용과 동일하지 않습니다. 나는 당신 undefined이 두 번째 부분 을 의미한다고 생각 하지 않습니다'undefined'
scaryguy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.