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


491

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

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

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

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

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

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

그러나이 형식은 널리 퍼져 있지 않으며, 악의 !=연산자 를 사용하는 것에 대해 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.