JavaScript에서 undefined 대신 null을 사용하는 이유는 무엇입니까?


103

저는 지금 꽤 오랫동안 JavaScript를 작성해 왔으며 .NET을 사용할 이유가 없었습니다 null. 그것은 undefined항상 바람직하고 프로그래밍 방식으로 동일한 목적을 제공합니다. null대신 사용 하는 실용적인 이유는 무엇입니까 undefined?


이것은의 가능한 중복 stackoverflow.com/questions/461966/...
lawnsea

document.getElementById()반환 할 수는 null있지만 반환 할 수 없는 메서드 가 있습니다 undefined. 이러한 경우 왜 반환을 테스트 undefined합니까? (물론, 그것은 당신이 사용하는 경우 일 것 ==보다는 ===, 여전히,하지만 왜 것 당신에게 잘못된 일에 대한 의도적으로 시험?)
에서 nnnnnn

예측 가능한 유형을 갖는 것이 도움이 될 수 있으며 이는 하나 또는 다른 유형을 사용하도록 생각하는 데 도움이 될 수 있습니다. 객체가 항상 반환되거나, 필요하거나, 의도적으로 필요한 경우 잘못된 결과에 대해 null을 사용합니다 (예 :) document.getElementById('does-not-exist'). 변수 var a;및 함수 반환 값은 기본적으로 undefined입니다. 과거에는 null이 전역 범위에 있었으므로 실행 속도가 느려지고 참조를 해제하는 데 다른 잘못된 유형 (false, '', 0)을 선호하게되었습니다. 나는 그것이 일반적으로 더 낫다고 생각하기 때문에 다른 설득력있는 이유가 없다면 개인적으로 null을 피합니다.
jimmont

답변:


59

Null과 undefined는 본질적으로 동일한 의미를 갖는 두 개의 다른 값입니다. 유일한 차이점은에 규칙 당신이 그들을 사용하는 방법의 당신의 시스템. 일부 사람들이 언급했듯이 어떤 사람들은 "객체 없음"을 의미하는 데 null을 사용합니다. 여기서 undefined는 객체가 예상되지 않았거나 오류가 있음을 의미하는 반면 가끔 객체를 얻을 수 있습니다. 내 문제는 완전히 임의적이고 완전히 불필요하다는 것입니다.

즉, 한 가지 큰 차이점이 있습니다. 초기화되지 않은 변수 (인수가 전달되지 않은 함수 매개 변수 포함)는 항상 정의되지 않습니다.

내 코드에서 나는 이유는 결코 내가 반환 널 (null) (예를 들어 정규식 일치)를 제어하지 않는 것을 제외하고는 null를 사용하지 않습니다. 이것의 아름다움은 사물을 많이 모방한다는 것입니다. x === 정의되지 않았는지 확인할 필요가 없습니다 || x === null. 그리고 == 또는 단순히 if (x) ... 같은 것을 사용하는 습관이 있다면. 멈춰. !x빈 문자열, 0, null, NaN에 대해 true로 평가됩니다. 즉, 원하지 않는 것입니다. 끔찍하지 않은 자바 스크립트를 작성하려면 항상 triple equals ===를 사용하고 null을 사용하지 마십시오 (대신 undefined 사용). 그것은 당신의 삶을 더 쉽게 만들 것입니다.


137
나는 이것에 동의하지 않는다. Null은 프로그래밍 방식으로 비어있는 것을 정의하는 데 사용됩니다. 정의되지 않음은 참조가 존재하지 않음을 의미합니다. null 값에는 "nothing"에 대한 정의 된 참조가 있습니다. 객체의 존재하지 않는 속성을 호출하는 경우 정의되지 않습니다. 이 속성을 의도적으로 비워 두려면 의도적으로 있음을 알 수 있도록 null이어야합니다. 많은 자바 스크립트 라이브러리가 이와 같이 작동합니다.
com2ghz

6
@ com2ghz 당신이 설명하는 것은 많은 철학 중 하나입니다. 많은 js 라이브러리가 실제로 그렇게 작동합니다. 많은 사람들도 그렇게 작동하지 않습니다. 자바 스크립트에서는 null을 사용하는 것처럼 명시 적 정의되지 않은 값을 객체 나 배열에 쉽게 저장할 수 있습니다. 둘 다의 의미는 완전히 문맥에 따라 다릅니다. IE는 당신이 원하는 것을 의미합니다.
BT

3
이것이 JS가 끔찍한 언어 인 이유입니다. 당신이 말했듯이 많은 도서관에는 자체 철학이 있지만 하나의 프로젝트에 많은 라이브러리를 포함합니다. 따라서 이러한 라이브러리의 많은 규칙을 접하게됩니다. 서로 다른 허위 검사를 몇 번이나해야합니까? null 객체를 문자열에 연결하고 "null"을 문자열로 얻는 것은 마지막이 아닙니다. 또는 숫자 값으로 0을 전달하고 IF 문이 처리하는 이유가 t가 거짓인지 궁금합니다.
com2ghz

2
@ com2ghz 그래서 JS는 null과 undefined를 모두 가지고 있기 때문에 끔찍한 언어입니까? 모든 주요 언어에서 수십 가지 잘못된 언어 결정을 셀 수 있습니다. js는 예외가 아닙니다. 나는 말 그대로 내 코드에서 허위 검사를 사용할 필요가 없거나 사용하고 싶지 않으며 항상 ===또는 !==. JS는 사용 방법을 안다면 환상적으로 표현적인 언어입니다.
BT

6
권리. JS의 초기 버전 이나 운영자 가 없었기 때문에 null/ undefined이분법이 필요 하다는 것을 방금 배웠습니다 . 이제 그 중 하나가 ES6 또는 내가 본 ES7 제안에서 왜 폐지되지 않았는지 이해하지 못합니다. hasOwnPropertyin
Andy

86

난 정말 답을 가지고 있지만, 따라하지 니콜라스 C. Zakas , 그의 책의 30 페이지의 " 웹 개발자를위한 전문 자바 스크립트 " :

나중에 객체를 보유 할 변수를 정의 할 때 null다른 변수와 는 반대로 변수를 로 초기화하는 것이 좋습니다 . 이렇게하면 값 null을 명시 적으로 확인 하여 나중에 변수가 개체 참조로 채워 졌는지 확인할 수 있습니다.


8
+1 예, 동의하며 항상 vars를 null로 초기화하는 것을 기억하려고합니다. 그렇다면 나는 undefined그것이 재난이 발생 했다는 것을 (꽤) 확신합니다 . 그냥 imho.
Pete Wilson

9
@Pete-하지만 "재해"에 대해 아무것도 알려주지 않습니다. 그래서 요점이 무엇입니까? 그리고 함수가 관례를 따르는 것을 아는 경우에만 그러한 가정을 할 수 있습니다.
RobG

7
반면에 변수를로 초기화하고 var myVar;undefined을 명시 적으로 확인 하여 나중에 개체 참조로 채워 졌는지 확인할 수도 있습니다. 내 요점은 이것은 완전히 학문적이라는 것입니다. 당신은 어느 쪽이든 할 수 있으며, 다른 방법으로 조언하는 사람은 단순히 자신의 컨벤션을 추진하는 것입니다.
thdoan

1
내가 가진 유일한 문제는 (15 년 전에 JavaScript로 시작한 이후로) 너무 자주 undefinednull. 이것은 여전히 ​​정말 성가신 일입니다. null추가 null테스트 횟수를 줄이기 위해 변수를 할당하지 않습니다 .
G Man

4
@GMan-이것은 ==비교 ===가 의미 가있는 유일한 장소입니다 : v == null(또는 v == undefined) null 또는 undefined를 확인합니다.
Rick Love

14

하루의 끝에서, 모두 있기 때문에 nullundefined같은 값으로 강제 변환 ( Boolean(undefined) === false && Boolean(null) === false), 당신은 기술적으로 작업을 끝내야 중 하나를 사용할 수 있습니다. 그러나 올바른 방법이 있습니다, IMO.

  1. 의 사용법은 undefinedJavaScript 컴파일러에 맡기십시오.

    undefined참조를 가리 키지 않는 변수를 설명하는 데 사용됩니다. JS 컴파일러가 당신을 돌봐 줄 것입니다. 컴파일 타임에 JS 엔진은 호이스트 된 모든 변수의 값을 undefined. 엔진이 코드를 단계별로 실행하고 값을 사용할 수있게되면 엔진은 해당 값을 각 변수에 할당합니다. 값을 찾지 못한 변수의 경우 변수는 계속해서 기본 요소에 대한 참조를 유지합니다 undefined.

  2. 변수의 값을 "값 없음"으로 명시하려는 경우에만 null을 사용하십시오.

    @ com2gz가 말했듯이 : null프로그래밍 방식으로 비어있는 것을 정의하는 데 사용됩니다. undefined참조가 존재하지 않음을 의미합니다. null값은 "아무것도"에 정의 된 기준을 갖는다. 객체의 존재하지 않는 속성을 호출하는 경우 undefined. 이 속성을 의도적으로 비워두면 의도적으로 있음 null을 알 수있을 것입니다.

TLDR; undefined프리미티브를 사용하지 마십시오 . 할당하지 않고 변수를 선언하거나 참조가없는 객체의 속성에 액세스하려고 할 때 JS 컴파일러가 자동으로 설정하는 값입니다. 반면에 null의도적으로 변수에 "값 없음"을 지정하려는 경우에만 사용 하십시오.

나는 명시 적으로 어떤 것도 undefined로 설정하지 않았습니다 (그리고 상호 작용 한 많은 코드베이스에서 이것을 발견하지 못했습니다). 또한 null. 내가 사용하는 유일한 null경우는 함수에 대한 인수 값을 값이없는 것으로 표시하려는 경우입니다. 즉,

function printArguments(a,b) {
  console.log(a,b);
}

printArguments(null, " hello") // logs: null hello

이것은 선택된 답변이어야합니다
alaboudi

13

undefined는 사물의 개념이 존재하지 않는 곳입니다. 유형이 없으며 해당 범위에서 이전에 참조 된 적이 없습니다. null은 사물이 존재하는 것으로 알려져 있지만 가치가 없습니다.


4
값을 할당하려고했지만 실패했고 대신 undefined 가 할당 되었는지 어떻게 알 수 있습니까?
RobG

11

모든 사람은 고유 한 코딩 방식과 고유 한 내부 의미를 가지고 있습니다.하지만 수년 동안 저는 이것이이 질문을하는 사람들에게 가장 직관적 인 조언이라는 것을 알게 되었습니다. 의심 스러울 때는 JavaScript가하는 일을하십시오. .

jQuery 플러그인 옵션과 같은 객체 속성을 사용하고 있다고 가정 해 보겠습니다. 아직 정의되지 않은 속성에 JavaScript가 제공하는 값이 무엇인지 직접 물어보세요 undefined. 답은 . 따라서이 컨텍스트에서 JavaScript와 일치하도록 'undefined'로 이러한 유형을 초기화합니다 (변수의 경우 var myVar;대신 할 수 있음 var myVar = undefined;).

이제 DOM 조작을하고 있다고 가정 해 보겠습니다. JavaScript가 존재하지 않는 요소에 할당하는 값은 무엇입니까? 대답은 null입니다. 이것은 나중에 DOM과 관련된 요소, 문서 조각 또는 유사 항목에 대한 참조를 보유 할 자리 표시 자 변수를 만드는 경우 초기화 할 값입니다.

당신이 JSON과 함께 작업하는 경우, 특별한 경우에 요구 될 수 있습니다 : 정의되지 않은 속성 값에 대해 다음 중 하나에 설정해야 ""또는 null값의 때문에undefined 적절한 JSON 형식으로 간주되지 합니다.

이 말한다면 이전의 포스터가 표현 된 것처럼, 당신은 당신이 물건을 초기화하고 있음을 발견 한 경우 null또는 undefined, 어쩌면 당신은 당신의 응용 프로그램을 코딩에 대해 이동하는 방법을 재고해야 더 블루 달에 한 번 이상.


이것은 좋은 입장이지만 다음 답변을 추가하고 싶습니다. stackoverflow.com/a/37980662/883303
Frederik Krautwald

@FrederikKrautwald 링크에 감사드립니다-그것은 매우 명확한 묘사입니다.
thdoan

10

여기에 제안 된 규칙을 채택 할 수도 있지만 실제로는 그럴만 한 이유가 없습니다. 의미가있을만큼 일관되게 사용되지 않습니다.

규칙을 유용하게 만들려면 먼저 호출 된 함수가 규칙을 따르는 지 알아야합니다. 그런 다음 반환 된 값을 명시 적으로 테스트하고 수행 할 작업을 결정해야합니다. 정의되지 않은 경우 호출 된 함수가 알고있는 일종의 오류가 발생 했다고 가정 할 수 있습니다 . 그러나 오류가 발생하고 함수가이를 알고 있고이를 더 넓은 환경으로 보내는 것이 유용하다면 오류 개체를 사용하지 않는 이유는 무엇입니까? 즉, 오류가 발생합니까?

따라서 하루가 끝나면이 컨벤션은 단순한 환경의 아주 작은 프로그램 외에는 거의 쓸모가 없습니다.


3

정의 되지 않은 null 의 유용한 속성은 다음 을 충족 하지 않습니다.

> null + 3
3
> undefined + 3
NaN

내가 사용하는 null내가 숫자 값을 '해제', 또는 일부를 초기화 할 때. 마지막 사용은 CSS 변환을 조작하는 것입니다.

const transforms = { perspective : null, rotateX : null };
// if already set, increase, if not, set to x
runTimeFunction((x) => { trasforms.perspective += x; });
// still useful, as setting perspective to 0 is different than turning it off
runTimeFunction2((x) => { transforms.perspective = null; });

// toCss will check for 'null' values and not set then at all
runTimeFunction3(() => { el.style.transform = toCss(transforms); });

이 속성을 사용 해야하는지 확실하지 않습니다 .


2

DOM 노드와 요소는 정의되지 않았지만 null 일 수 있습니다.

  • 요소의 마지막 자식의 nextSibling이 null입니다.

  • 첫 번째 자식의 previousSibling이 null입니다.

  • 요소가 문서에없는 경우 document.getElementById 참조는 null입니다.

그러나 이러한 경우에 정의되지 않은 값은 없습니다 . 거기에는 노드가 없습니다.


설명 해주셔서 감사합니다. 나에게 이것은 더 직관에 반하는 것이 될 수 없습니다.
tomekwi

실제로 확인하려는 내용에 따라 다릅니다. 예를 들어, 'myVar'라는 전역 변수가 있는지 확인하려면 존재 window.myVar하지 않으면 'undefined'를 반환합니다. 자바 스크립트에서 '정의되지 않음'을 반환하는 수많은 항목이 있으며 'null'을 반환하는 항목이 매우 많습니다. 모두 컨텍스트에 따라 다릅니다.
thdoan

2

몇몇은 객체를 null. Destructuring 인수 기본값이 .NET에서 작동하지 않는다는 점을 지적하고 싶었습니다 null. 예를 들면 :

const test = ({ name } = {}) => {
  console.log(name)
}

test() // logs undefined
test(null) // throws error

자주 발생할 수있는 함수를 호출 하기 전에null 확인을 수행해야합니다 .


1

나는 지금이 정확한 질문에 대해 작업하고 있으며 다음 철학을보고 있습니다.

  1. 결과를 반환하려는 모든 함수는 결과를 찾지 못하면 null을 반환해야합니다.
  2. 결과를 반환하지 않는 함수는 암시 적으로 undefined를 반환합니다.

나 에게이 질문은 결과를 반환하는 함수를 호출하는 사람은 정의되지 않은 대 null을 테스트할지 여부에 대해 질문이 없어야하기 때문에 중요합니다.

이 답변은 다음 사항을 다루지 않습니다.

  1. null과 undefined의 속성 값
  2. 함수 내의 변수가 null vs undefined

내 생각에 변수는 API의 일부가 아니라 자신의 비즈니스이며 모든 OO 시스템의 속성은 정의되어 있으므로 정의되지 않은 경우와 다른 값으로 정의해야합니다 (정의 된 경우 null, 정의되지 않은 것은 사용자 객체에없는 무언가에 액세스 할 때 얻을 수 있습니다).


1

이유 var undefined = 1 는 다음과 같습니다. 합법적 인 자바 스크립트이지만 var null = 1구문 오류입니다. 차이점은 null언어 키워드이지만undefined 어떤 이유로 든 그렇지 않다는 것입니다.

코드 가 그 이름으로 변수를 정의하지 않았기 때문에 작동 undefined하는 키워드 ( if (foo == undefined)-만들기 매우 쉬운 실수) 인 것처럼 비교에 의존하는 경우 . 이 모든 코드는 실수로 또는 악의적으로 해당 이름으로 전역 변수를 정의하는 사람에게 취약합니다. 물론, 우리 모두는 실수로 전역 변수를 정의하는 것이 자바 스크립트에서 완전히 불가능하다는 것을 알고 있습니다.


1
void 0정의되지 않은 대신 사용하십시오 .
Frederik Krautwald 2016 년

1

특정 자바 스크립트 라이브러리를 사용하면 null 및 undefined가 의도하지 않은 결과를 초래할 수 있습니다.

예를 들어, get기본값을 세 번째 인수로 받아들이는 lodash의 함수 :

const user = {
  address: {
    block: null,
    unit: undefined,
  }
}
console.log(_.get(user, 'address.block', 'Default Value')) // prints null
console.log(_.get(user, 'address.unit', 'Default Value')) // prints 'Default Value'
console.log(_.get(user, 'address.postalCode', 'Default Value')) // prints 'Default Value'

또 다른 예 : React에서 defaultProps를 사용하는 경우 속성이 전달 null되면 null이 정의 된 값으로 해석 되므로 기본 props가 사용되지 않습니다 . 예 :

class MyComponent extends React.Component {
   static defaultProps = {
      callback: () => {console.log('COMPONENT MOUNTED')},
   }
   componentDidMount() {
      this.props.callback();
   }
}
//in some other component
<MyComponent />   // Console WILL print "COMPONENT MOUNTED"
<MyComponent callback={null}/>   // Console will NOT print "COMPONENT MOUNTED"
<MyComponent callback={undefined}/>   // Console WILL print "COMPONENT MOUNTED"

0

null 또는 undefined 사용이 불필요하다는 데 완전히 동의하지 않습니다. undefined는 전체 프로토 타입 체인 프로세스를 유지하는 것입니다. 따라서 null 만있는 컴파일러는이 속성이 null인지 아니면 끝점 프로토 타입에 정의되어 있지 않은지 확인할 수 없습니다. 다른 동적 유형 언어 (fe Python)에서는 정의되지 않은 속성에 액세스하려는 경우 예외가 발생하지만 프로토 타입 기반 언어의 경우 컴파일러는 부모 프로토 타입도 확인해야하며 여기에서 정의되지 않은 것이 가장 필요한 곳이 있습니다.

null 사용의 전체적인 의미는 변수 나 속성을 singleton이고 공허함을 의미하는 객체와 결합하는 것 뿐이며, null 사용도 성능 목적을 가지고 있습니다. 이 두 코드는 실행 시간이 다릅니다.

var p1 = function(){this.value = 1};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p1();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0)

var p2 = function(){this.value = 1, p.x = null};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p2();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p; 
});
big_array.reduce((sum, p)=> sum + p.value, 0)

0

알 수없는 변수 : undefined .

알려진 변수이지만 값이 없음 : null.

  1. 서버에서 개체를 받고 server_object ..
  2. 당신은 server_object.errj. 그것은 당신에게 그것이undefined . 그것은 그것이 무엇인지 모른다는 것을 의미합니다.
  3. 이제 server_object.err. 그것은 당신에게 그것을 알려줍니다 null. 이는 올바른 변수를 참조하고 있지만 비어 있음을 의미합니다. 따라서 오류가 없습니다.

문제는 값없이 변수 이름을 선언 할 때입니다 ( var hello) js는 다음과 같이 선언합니다 undefined.이 변수는 존재하지 않습니다. 프로그래머는 대부분 "아직 가치를 부여하지 않았습니다"라는 뜻입니다.null .

따라서 프로그래머의 기본 동작 (값이없는 변수를 아무것도없는 것으로 선언)은 js와 상충되며 존재하지 않는 것으로 선언합니다. 게다가, !undefined!null모두true 그래서 대부분의 프로그래머는 그것들을 동등하게 취급합니다.

당신은 물론 당신이 항상 보장 할 수 var hello = null있지만, 대부분은 의도적으로 느슨하게 입력 언어 형 정신을 보장하기 위해 같은 쓰레기 자신의 코드를하지 않습니다 때와 !운영자 치료 모두 undefinednull동등있다.

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