typeof! ==“undefined”vs.! = null


491

정의되지 않은 매개 변수 등을 확인하는 JavaScript 코드가 종종 있습니다.

if (typeof input !== "undefined") {
    // do stuff
}

형식 조회와 문자열 비교가 포함되어 있기 때문에 다소 낭비 적입니다. undefined이름을 바꿀 수 있기 때문에 필요합니다 .

내 질문은 :
이 코드는이 접근법보다 나은 방법입니다.

if (null != input) {
    // do stuff
}

내가 아는 한 재정의 할 수 없으므로 null예기치 않게 중단되지 않습니다. 그리고, !=연산자 의 타입 강제 때문에 , 이것은 당신이 원하는 것 (예를 들어 선택적 함수 매개 변수) undefinednull정확히 같은 것을 모두 검사합니다 .

그러나이 형식은 널리 퍼져 있지 않으며, 악의 !=연산자 를 사용하는 것에 대해 JSLint가 소리를 지르게합니다 .

이것이 왜 나쁜 스타일로 간주됩니까?


13
@ Marcel, 실제 차이는 없지만 두 가지 이유가 있습니다. 하나는 일부는 읽기가 더 명확하다는 것입니다. 두 번째 이유는 실수로 변수를 덮어 쓰는 것을 방지하기 위함입니다. 비교하려고 할 때 if (foo = "value")를 수행 한 적이 있습니까? 대입 / 비교 연산자에서 변수를 뒤집는 습관을 들이는다면 그 문제는 없을 것입니다.
Layke

29
일부 (나 포함)의 경우 실제로는 읽기 가 더 어렵 습니다. 또한 대부분의 IDE는 실수로 할당되었음을 경고합니다. 그러나 비교 변수가 매우 길면 여전히이 양식을 사용합니다. YMMV.
johndodo

15
@MarcelKorpel 이것을 "요다 조건"이라고합니다 : umumble.com/blogs/Programming/321
kol

55
읽기가 더 어렵습니다. "병이 비어 있지 않다"고 말하지 않습니다.
Noel Abrahams

11
if (null != input)"Yoda Speak"는 영어 스피커 (I one ... 오전 .uuammmmm)에게만 적용되므로 같은 것과 동일하면 의미에 불과합니다. 이모.
webLacky3rdClass

답변:


709

typeof 식별자가 이전에 선언되지 않았으므로 더 안전합니다.

if(typeof neverDeclared === "undefined") // no errors

if(neverDeclared === null) // throws ReferenceError: neverDeclared is not defined

3
if ((typeof neverDeclared! == "undefined") && (neverDeclared! == null)) {return true; } else {return false; }
Anthony DiSanti

88
null / undefined와 비교할 때 ===를 사용하십시오.
MyGGaN 2016 년

47
@MyGGaN은 둘을 구별하려는 경우에만 가능합니다. 대부분의 경우 ==null과 undefined를 모두 테스트하기 때문에 더 나을 수 있습니다.
seanmonstar 2016 년

10
typeof가 항상 문자열을 반환하기 때문에 typeof somevar == 'undefined'와 typeof somevar === 'undefined'의 차이점을 찾을 수 없습니다. null 인 경우 'object'를 반환합니다. 아니면 내가 틀렸을 수 있습니까?
TomTom

2
@TomTom의 의견이 문제의 핵심이라고 생각 합니다. 유형이 문자열이라고 알려진 값을 비교할 때 !==or ===연산자를 사용하는 이유를 이해할 수 없습니다 .
Nicolas Rinaudo

49

변수가 var키워드, 함수 인수 또는 전역 변수로 선언 되면 가장 좋은 방법은 다음과 같습니다.

if (my_variable === undefined)

jQuery는 그것을 수행하므로 나에게 충분합니다 :-)

그렇지 않으면를 typeof피하기 위해 사용해야 합니다 ReferenceError.

undefined가 재정의 될 것으로 예상되면 다음과 같이 코드를 래핑 할 수 있습니다.

(function(undefined){
    // undefined is now what it's supposed to be
})();

또는 void연산자 를 통해 얻습니다 .

const undefined = void 0;
// also safe

1
undefined가 이미 정의되어 있으면 undefined라는 매개 변수를 통해 익명 함수에 전달하지 않고 아무것도 수행하지 않습니까?
Anthony DiSanti

20
@Anthony DiSanti : 아니요, undefined값이 아닌 함수 매개 변수에 지정된 이름입니다. 함수에 아무것도 전달되지 않으므로 첫 번째 매개 변수의 값이 정의되지 않았습니다.
Joey Adams

3
아 내 실수, 추적 해줘서 고마워 투표권을 삭제했습니다. 죄송합니다.
Anthony DiSanti

2
다른 개발자가 선언하지 않은 선언을 처리하기 위해 예외를 작성 해야하는 이유는 무엇입니까? jQuery는 정의되지 않은 크기가 정의되지 않았으며 축소 된 크기를 줄이기 위해 함수에 표시 할 때 초기 익명 함수를 래핑합니다. 예상치 못한 결과가 이런 식으로 발생할 수 있다면 간단히 입력하십시오. (lazy programming이 입력을 피할 위험이 있습니다 (typeof variable === 'undefined'). 우리가 원한다면 (typeof variable === 'object') 우리가 할 수있는 객체 인 기본 변수를 제공해야합니까 (variable === object)?
fyrye

28

좋은 방법 :

if(typeof neverDeclared == "undefined") //no errors

그러나 가장 잘 보이는 방법은 다음을 통해 확인하는 것입니다.

if(typeof neverDeclared === typeof undefined) //also no errors and no strings

6
var undefined = 함수 () {}; if (typeof neverDeclared === typeof undefined); neverDecalred! = '함수'; jsfiddle.net/hbPZ5는 var의 type을 반환합니다. 문자열을 반환합니다. 오류나 문자열이 없지만 항상 예상되는 결과를 제공하지는 않습니다. 권한이 부여 된 개발자는 정의되지 않은 것을 선언해서는 안되지만이를 수행하는 프레임 워크와 라이브러리가 있습니다.
fyrye

1
나는 주로 사용 if (typeof neverDeclared === typeof undefined) { 하지만 Lint는 오류를 발생시킵니다. "문자열을 예상하고 대신 'typeof'를 보았습니다." 이 오류를 어떻게 해결할 수 있습니까? Lint의 요구에 복종하고 대신 '좋은 방법'을 사용해야합니까?
Ayelis

2
@fyrye 실제로 undefined를 변경하는 JavaScript 라이브러리 / 프레임 워크를 알고 있습니까? 나는 그것이 가능하다는 것을 안다. 그러나 나는 "여기서이 엉뚱한 누우를 만날 수있는 곳이 있습니다!"
bigtunacan

4
typeof neverDeclared === typeof void 0;-D
Alex Yaroshevich

1
실제로는 정의되지 않은 특정 변수 ( "정의되지 않은")에 의존하기 때문에 오류가 발생하기 쉽습니다. 다른 게시물에서 알 수 있듯이 거짓 일 수 있습니다. 당신은 항상 할 수 if(typeof neverDeclared === typeof undefined_variable_with_a_name_assumed_to_be_never_defined) {있지만 다소 길다.
Pierre-Olivier Vares

12

정의되지 않은 이름이 바뀌는 것에 대해 걱정할 필요가 없습니다. 누군가가 정의되지 않은 이름을 바꾸면 수표가 실패하는 것보다 몇 가지 문제가 더 많습니다. 코드를 실제로 보호하려면 다음과 같이 IFFE (즉시 호출 된 함수 표현식)로 코드를 래핑하십시오.

(function($, Backbone, _, undefined) {
    //undefined is undefined here.
})(jQuery, Backbone, _);

브라우저 환경에서 전역 변수 (이미 잘못된)로 작업하는 경우 다음과 같이 정의되지 않은지 확인합니다.

if(window.neverDefined === undefined) {
    //Code works
}

전역 변수는 창 개체의 일부이므로 문자열로 캐스팅하고 문자열을 비교하는 대신 정의되지 않은 변수를 간단히 확인할 수 있습니다.

무엇보다 변수가 정의되지 않은 이유는 무엇입니까? 변수 존재를 확인하고 그에 따라 몇 가지 작업을 수행하는 많은 코드를 보았습니다. 이 접근법이 올바른 곳을 한 번도 보지 못했습니다.


1
입력 유효성 검사 및 종속성 검사가이를 사용하는 좋은 이유입니다. 로드되었거나 init 객체가 선언 된 다른 파일에 의존하는 Javascript 파일이있는 경우 파일이 정의되지 않은 객체 또는 속성을 테스트하고 스크립트가 예측할 수없는 곳에서 실패하는 대신 멋진 예외를 발생시키는 것이 유용합니다.
AmericanUmlaut

그것은 당신이 AMD (require.js)의 라인에 뭔가가 필요할 것 같습니다
Peeter

1
또는 내 프로젝트에 다른 라이브러리를 포함시키는 대신 매우 간단한 비교를 원할 수도 있습니다. :)
AmericanUmlaut

너무 늦었습니다 :(. 추가하고 싶었습니다-require.js는 입력 유효성 검사에 대한 올바른 솔루션이 아닙니다 (초기 주석에서 언급 한 init 객체). 스크립트가로드되기 전에 값을 정의하면 정의되지 않은 경우 예외를 처리하는 것이 좋습니다
AmericanUmlaut

1
아니요. typeof는 문자열을 반환하기 때문입니다. 따라서 typeof undefined는 "undefined"를 반환합니다. window.input! == undefined (변수가 전역 spoce에있는 경우)
Peeter

5

정의되지 않은 재정의가 정말로 걱정된다면 다음과 같은 도우미 메소드를 사용하여 이것을 막을 수 있습니다.

function is_undefined(value) {
   var undefined_check; // instantiate a new variable which gets initialized to the real undefined value
   return value === undefined_check;
}

이것은 누군가가 글 undefined = "foo"을 쓸 때 이름 만 허용 하기 때문에 작동합니다 undefined 이 새로운 값을 참조하도록 허용하지만 실제 값은 변경하지 않기 때문에 작동 undefined합니다.


1
그러나 이제 성능을 저하시키는 함수 호출을 도입했습니다.
Tim Down

이 함수 호출이 성능을 저하시킬 것이라고 생각하지 않습니다. DOM이 병목 현상이 발생할 가능성이 훨씬 큽니다. 그러나 어쨌든 라이브러리가 포함 된 일반적인 큰 익명 함수가 있다면 undefined_check맨 위에 정의 한 다음 코드의 어느 곳에서나 사용할 수 있습니다.
Ivo Wetzel

1
동의하며, 이것이 나쁜 생각은 아닙니다. 이 함수를 호출하면 typeof검사를 수행하는 것보다 느리게 수행됩니다 .
Tim Down

이 기능은 인라인 될 정도로 간단하므로 성능에 영향을 미치지 않습니다.
huyz

4
@TimDown : 첫 번째 코드 작성, 읽을 수 있습니다. 두 번째 쓰기 코드는 유지 관리가 가능하고 실제로 느리게 진행되는 경우입니다. 그런 다음 성능에 대해 생각하십시오.
andreas

4

void 연산자를 사용하여 정의되지 않은 값을 얻을 수도 있습니다.

if (input !== void 0) {
    // do stuff    
}

(그리고 다른 대답에서 언급했듯이 변수가 선언되지 않으면 오류가 발생하지만이 경우 코드 검사 또는 코드 리팩토링 (예 : window.input !== void 0전역 변수 테스트 또는 추가 var input) 으로 배제 될 수 있습니다 .


1

(typeof input !== 'undefined')이 시나리오에서 기본 기능 매개 변수를 제공하는 데 실제로 사용되는 경우 실제로 나왔습니다 .

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

ES6는 다음과 같이 기본 기능 매개 변수를 도입하는 새로운 방법을 제공합니다.

function greet(name = 'Student', greeting = 'Welcome') {
  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

이것은 첫 번째 옵션보다 덜 장황하고 깨끗합니다.


1

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  console.log(greeting,name);
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

//ES6 provides new ways of introducing default function parameters this way:

function greet2(name = 'Student', greeting = 'Welcome') {
//  return '${greeting} ${name}!';
console.log(greeting,name);
}

greet2(); // Welcome Student!
greet2('James'); // Welcome James!
greet2('Richard', 'Howdy'); // Howdy Richard!


0

(function(){

  var a= b = 3;
  var ed = 103;
  
})();



//console.log(ed); //ed is not defined

console.log("a defined? " + (typeof a !== 'undefined')); //no define
console.log("b defined? " + (typeof b !== 'undefined')); //yes define
console.log(typeof(b)); //number
console.log(typeof(4+7));   //number
console.log(b); //3
console.log(typeof("4"+"7")); //string
var e= "ggg";
console.log(typeof(e)); //string
 var ty=typeof(b);
console.log(ty); //number
console.log(typeof false); //boolean
console.log(typeof 1); //number
console.log(typeof 0); //number
console.log(typeof true); //boolean


console.log(typeof Math.tan);  //function
console.log(typeof function(){}); //function 

if(typeof neverDeclared == "undefined") //no errors
if(typeof neverDeclared === "undefined") //no errors

//if(neverDeclared == null) //showing error 


console.log(typeof {a:1}); //object
console.log(typeof null); //object
console.log(typeof JSON); //object
console.log(typeof Math); //object
console.log(typeof /a-z/); //object
console.log(typeof new Date()); //object

console.log(typeof afbc); //undefined
//console.log(typeof new);//error

document.write("<br> * oprator as math ");
var r=14*"4";
document.write(r);

document.write("<br> + oprator as string ");
var r=14+"44";
document.write(r);

document.write("<br> Minus Operator work as mathematic ");
var r=64-"44";
document.write(r);


document.write("<br>");
console.log(typeof(4*"7")); //returns number
console.log(typeof(4+"7")); //returns string




 
Interview Question in JavaScript


설명을 해줄 수 있습니까?
jhpratt GOFUNDME 라이센스 갱신

typeof가 반환 할 수있는 값은 object, boolean, function, number, string 및 undefined입니다. typeof 연산자는 피연산자의 데이터 유형 (문자열을 리턴)을 가져 오는 데 사용됩니다. 피연산자는 리터럴 또는 변수, 함수 또는 객체와 같은 데이터 구조 일 수 있습니다. 연산자는 데이터 유형을 반환합니다. 구문 대해서 typeof 피연산자 또는 대해서 typeof (피연산자)
Avinash 마우리

0

var bar = null;
console.log(typeof bar === "object"); //true yes 
//because null a datatype of object

var barf = "dff";
console.log(typeof barf.constructor);//function


console.log(Array.isArray(bar));//falsss


console.log((bar !== null) && (bar.constructor === Object)); //false

console.log((bar !== null) && (typeof bar === "object"));  // logs false
//because bar!==null, bar is a object


console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function"))); //false

console.log(typeof bar === typeof object); //false
console.log(typeof bar2 === typeof undefined); //true
console.log(typeof bar3 === typeof undefinedff); //true
console.log(typeof bar2 == typeof undefined); //true

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]")); //false


-7
if (input == undefined) { ... }

잘 작동합니다. 물론 null비교는 아니지만 일반적으로 undefined와 를 구별 해야하는 경우 null실제로는 실제로는 undefined거짓 값 을 구별해야 하므로

else if (input) { ... }

그렇습니다.

프로그램이 재정의되면 undefined어쨌든 그것은 정말 두뇌입니다.

내가 생각할 수있는 유일한 이유는 IE4 호환성 때문이었습니다. undefined실제로 키워드는 이해하지 못했지만 (실제로는 키워드는 아니지만) 물론 값은 있습니다undefined .

var undefined;

위의 비교는 잘 작동합니다.

두 번째 예에서 보푸라기를 행복하게하려면 이중 괄호가 필요합니까?


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