JavaScript에 'null'값이있는 이유는 무엇입니까?


116

JavaScript에는 기본적으로 'I do n't exist' undefinednull.

프로그래머가 아무것도 할 것이다 할당되지 않은에 속성 undefined이 될 수있는 속성에 대해,하지만 순서는 null, null명시 적으로 할당해야합니다.

나는 한때 원시적 가치와 객체 null이기 때문에 필요가 있다고 생각했습니다 . 양보 하지 않습니다 . 사실 둘 다 원시 값입니다. 즉 , 둘 다 빈 객체로 변환되므로 생성자 함수에서 반환 할 수도 없고 반환 할 수도 없습니다 (생성자에서 실패를 선언하려면 오류를 발생시켜야합니다).undefinednulltypeof null'object'undefinednull

또한 둘 다 false부울 컨텍스트에서 평가 됩니다. 내가 생각할 수있는 유일한 차이점은 하나는으로 평가되고 NaN다른 하나 0는 숫자 컨텍스트에서 평가된다는 것입니다 .

그렇다면 왜 둘 다 undefined있고 null이것이 null속성이 설정되었는지 여부를 찾으려고 할 때 잘못 확인하는 프로그래머를 혼란스럽게한다면 ?

내가 알고 싶은 것은 누군가 대신 null사용하여 표현할 수없는 사용 이 필요한 합리적인 예가 있는지 여부 undefined입니다.

그래서 일반적인 합의는 undefined'그런 재산이 없다 null'는 의미 이고 '재산이 존재하지만 가치 가 없다'는 의미 인 것 같습니다 .

자바 스크립트 구현이 실제로이 동작을 강제 할 수 있다면 그와 함께 살 수 있습니다. 그러나 undefined완벽하게 유효한 기본 값이므로 기존 속성에 쉽게 할당하여이 계약을 위반할 수 있습니다. 따라서 속성이 있는지 확인하려면 in연산자 를 사용해야 hasOwnProperty()합니다. 다시 한 번 : undefined및에 대한 별도의 값에 대한 실제 사용은 null무엇입니까?

undefined더 이상 사용하지 않지만 원하지 않는 속성 값을 설정 해제하고 싶을 때 실제로 사용 합니다 delete. null대신 사용해야합니까 ?


3
마지막 질문에 답하려면 : 아니요, 속성을로 설정하면 안됩니다 undefined.
Shog9

4
"정의되지 않음"은 기본 값이 "정의되지 않음"인 전역 범위의 변수입니다. 변수에 다른 값을 정의 할 수 있습니다. {undefined = "Hello"; 경고 (정의되지 않은);}에 대한 시험을보다 신뢰할 수있는 방법 정의되지 않은 : {(대해서 typeof myVar에 === "정의되지 않은") 경고 ( "정의되지 않은")}의 경우
일부

1
undefined / null에 대해서는 ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf의 4.3.9-12 절을 참조 하고 전역 범위의 "undefined"변수에 대해서는 15.1.1.3을 참조하십시오.
일부

1
더 의미가있는 경우 개체를 삭제하거나 null로 설정해야하지만 undefined는 아닙니다.
일부

4
In JavaScript, there are two values which basically say 'I don't exist' - undefined and null.아니, undefined그게 다야.
궤도에서 가벼운 경주

답변:


78

질문은 실제로 "JS에 null 값이있는 이유"가 아닙니다. 대부분의 언어에는 일종의 null 값이 있으며 일반적으로 매우 유용한 것으로 간주됩니다.

질문은 " JS에 정의되지 않은 값 이있는 이유 "입니다. 사용되는 주요 장소 :

  1. 선언 var x;했지만 할당하지 않으면 x정의되지 않은 상태로 유지됩니다.
  2. 함수가 선언 한 것보다 적은 인수를받을 때;
  3. 존재하지 않는 개체 속성에 액세스 할 때.

null확실히 (1)과 (2) *에 대해 잘 작동했을 것입니다. (3) 실제로 예외를 즉시 던져야하며, undefined나중에 실패 할 이상한 것을 반환하는 대신에 예외를 반환하지 않는다는 사실 은 디버깅 어려움의 큰 원인입니다.

* : (2) 예외가 발생해야한다고 주장 할 수도 있지만 기본 / 변수 인수에 대해 더 명확하고 더 명확한 메커니즘을 제공해야합니다.

그러나 JavaScript에는 원래 예외가 없었거나 특정 이름의 멤버가 있는지 객체에 요청하는 방법이 없었습니다. 유일한 방법은 멤버에 액세스하고 얻을 수있는 내용을 보는 것뿐이었습니다. 점을 감안 null이미 목적을 가지고 당신이 잘하는 멤버가 다른 대역 값이 필요했다을 설정할 수 있습니다. 그래서 우리는 undefined당신이 지적한 것처럼 문제 가 있으며 , 우리가 결코 제거 할 수없는 또 다른 훌륭한 자바 스크립트 '기능'입니다.

더 이상 사용하지 않지만 삭제하고 싶지 않은 속성 값을 설정 해제하고 싶을 때 실제로 undefined를 사용합니다. 대신 null을 사용해야합니까?

예. undefined다른 언어에서 예외가 발생할 수있는 경우 신호를 보내는 특수 값으로 유지하십시오 .

null를 설정 null하면 오류가 발생할 수 있는 일부 IE DOM 인터페이스를 제외하고는 일반적으로 더 좋습니다 . 종종이 경우 빈 문자열로 설정하면 작동하는 경향이 있습니다.


10
Args는 확장 가능합니다. 원하는만큼 드롭 할 수 있으며 함수는 잠재적으로 반복하여 모두 사용할 수 있습니다. 객체에는 언제든지 새 속성을 할당 할 수 있습니다. 둘 다 강력한 기능이지만 원하는대로 예외가 발생하면 많은 오버 헤드가 발생한다고 생각합니다. IMO, 그만한 가치가 있습니다. 더 엄격한 언어 패러다임으로 캐스팅하는 것보다 JS에서 존재 여부를 확인하는 데 훨씬 적은 시간을 소비합니다.
Erik Reppen 2014 년

질문에 대한 허용 된 답변이 "이것은 실제로 질문이 아닙니다 ..."로 시작하는 방법을
Phillip

@bobince 초기 버전의 JS에는 in연산자가 hasOwnProperty없습니까? obj.hello !== undefined객체에 속성이 있는지 확인하는 것보다 훨씬 안전하기 때문 입니다.
Andy

신경 쓰지 마, 나는 내 질문에 답했다. MDN에 따르면 둘 다 ES3에 도입되었습니다.
Andy

37

여기에 가장 잘 설명 되어 있지만 요약하면 다음과 같습니다.

undefined는 유형과 값이없는 것이고 null은 값이없는 것입니다.

또한 간단한 '=='비교를 수행하면 맞습니다. 그러나 유형과 값을 모두 비교하는 ===를 시도하면 차이를 알 수 있습니다.


1
내가 알고 null !== undefined, 같은 의미 론적 개념을 표현하는 두 가지에 대한 필요가 왜 내 질문이었다 - ... 그것은 원시적이다, 잘못 - 또한, 귀하의 링크는 '널 (null)가 객체'고 언급
크리스토프

2
그것들은 동일한 의미 론적 개념이 아닙니다. 적어도 나에게는 null 값이 할당 된 속성과 존재하지 않는 속성 사이에 중요한 차이가 있습니다.
Daniel Schaffer

그러나 그것은 단지 그것입니다. 그들은 같은 의미 론적 개념이 아닙니다. 프로그래머의 편의를 위해 ==를 사용하여 동일한 것을 암시하는 경우 Null이 강제됩니다.
Eddie Parker

1
@EricElliott : typeof거짓말 - 사양을 읽거나 반환하려고 null생성자에서
크리스토프

5
@EricElliott : 생성자의 반환 값은 허위 성과 관련이 없지만 객체 성입니다. 반환 값이 객체이면 반환합니다. 이 같은 원시적 인 경우 null또는 42반환 값을 무시하고 대신 새로 생성 된 개체를 반환
크리스토프

17

나는 모두를 할 이유가 없다고 생각 null하고 undefined유일한 이유는 많은 사람들이 제안했기 때문에 ( " undefined자바 스크립트 적어도하지 유효 그런 변수 / 속성이 없다 수단"). undefined변수 / 속성이 존재하는지 여부를 말할 수 없습니다.

console.log(foo);               // "ReferenceError: foo is not defined"
                                // foo does not exist
var foo;
console.log(foo);               // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist

var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined);     // "true", but it does exist

obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted

보시다시피 확인 foo === undefinedfoo존재 여부를 알려주지 obj.bar = undefined않으며 설정 은 실제로 bar.

undefined"존재하지 않음"을 나타내는 것은 JavaScript 작성자의 원래 의도 일 수 있습니다 . 그러나 구현은 그렇게되지 않았습니다.


1
교체 undefinednull당신의 위의 코드 예제, 그리고 응답은 모두 동일합니다. 이것이 질문에 어떻게 대답하는지 잘 모르겠습니다. 다른 사람의 답변에 대한 의견 이었습니까?
Eric Elliott

1
@EricElliott 질문에 대한 나의 대답은 많은 사람들이 제안한 유일한 이유가 유효하지 않기 때문에 null와 둘 다 가질 undefined이유가 없다는 것입니다.
Lei Zhao

답을 수정하고 실제로 그렇게 말해야합니다. 당신이 그 대답을했다면 나는 찬성했을 수도 있습니다. =)
Eric Elliott

@EricElliott 나는 당신이 옳다고 생각합니다. 내 대답을 수정했습니다. 감사!
Lei Zhao

3
이 예제는 실제로 변수를 할당하지 않은 경우 undefined. 그러나 할당했다면 undefined실제로는 아닙니다. undefined정의 undefined되고 참조가 있습니다. 유일한 차이점 undefinednull사용법, 역사적 목적이다. 둘 다 원자 적입니다.
Aleksej Komarov 2014

6

둘 다 필요로하는 것은 전적으로 가능합니다. 예를 들어 WMI를 쿼리하는 경우 null 값이있는 클래스 반환 속성을 가질 수 있습니다. 그들은 정의되어 있으며, 당시에 null을 유지합니다.


6

나는 자바 스크립트 undefined가 "그런 속성이 없다"고 null"속성이 가치가 없다 "고 정의한다는 당신의 결론 은 완벽하게 옳다고 생각합니다. 그리고 JavaScript와 같은 동적 언어에서는 매우 중요한 차이입니다. 덕 타이핑을 사용한다는 것은 존재하지 않는 속성과 값이없는 속성을 구별 할 수 있어야 함을 의미합니다. 유형 정보를 파생하는 기본 수단입니다. 정적으로 형식화 된 언어에서는 필드가 null 인 필드와 존재하지 않는 필드가 분명하게 구분됩니다. JavaScript에서 이것은 다르지 않습니다. 그러나 런타임시 확인되며 그 때까지 수정할 수 있습니다.

많은 시간이 흐려지면서 구현이 이상하다는 데 동의해야 할 것입니다. 그러나 JavaScript에서는 구별이 중요하다고 생각합니다. 그리고 할당 할 수 있어야합니다 undefined.

얼마 전에 JavaScript로 작성된 온라인 RPG에 대한 블로그 게시물을 읽은 기억이 있습니다. 개체가 프로토 타입 (클래스, 함수 등)이 아닌 기존 인스턴스의 복사본으로 생성 된 다음 변경된 예제를 사용했습니다. 이로 인해 undefined기존 개체를 수정할 때 얼마나 강력한 지 이해하게 되었지만 누가 작성했는지 기억할 수 없습니다.


이 RPG를 공유해 주시겠습니까?
Michael

3

의미 적으로 그들은 다른 것을 의미합니다. null 유형은 도메인에 정확히 하나의 값을 가지며 null 및 속성에이 특정 값이 할당 될 수 있습니다. 정의되지 않음은 할당 된 값의 뚜렷한 부족을 나타냅니다.


1
그러나 당신은 undefined속성에 할당하기 위해 잘 사용할 수 있습니다 . 그래서이 계약 (해당 undfined속성이없는 경우 에만 반환 )은 프로그래머에 의해 쉽게 깨질 수 있습니다.
Christoph

2
당신 은 할 수 있지만, 당신은 가장 확실히해서는 안됩니다. Undefined는 JavaScript에서 매우 기본적이고 단순한 형태의 예외로 사용됩니다. 값으로 사용하지 말고 일부 속성에 할당하십시오! 미친놈이야.
rfunduk

3

Java 프로그래머로서 저는 undefined와 null의 큰 차이를 봅니다. JavaScript는 강력한 유형이 아니기 때문에 JavaScript 코딩은 그리 많지 않으며, undefined와 null의 차이는 런타임에서 자주 수행되는 자동 변환으로 인해 희미 해집니다. BTW, 저는 이러한 변환을 자주 활용합니다. 그들은 내 JS 코드를 더 간결하고 읽기 쉽게 만듭니다.

질문에 대답하기 위해 정의되지 않음은 값이 설정되지 않았 음을 의미합니다. 실제로 이것은 일반적으로 버그를 가리 킵니다. yourObject.property가 정의되지 않은 경우 어떤 이유로 든 속성을 설정하지 않았거나 전혀 존재하지 않는 것을 찾고 있다는 의미입니다. 이것은 둘 이상의 코더가있는 프로젝트에서 작업 할 때 실제 문제입니다.

null은 "값 없음"이 명시 적으로 설정되었음을 의미합니다. 실질적으로 말해서, 당신은 속성에 대해 뭔가를 말하고 있습니다. 아마도이 상황에서 사용되지 않았거나 값이 아직 결정되지 않았을 것입니다.

Java에서 정의되지 않은 필드에 액세스하려고하면 항상 예외가 발생합니다. 실제로 컴파일러는 코드에서 이에 대해 경고하도록 만들 수 있습니다.


0

이 예를 시도하십시오.

<html>
<head>
    <script type="text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

여기에 2 가지 다른 유형에 대한 매우 실제 사용이 있다고 생각합니다.


그리고 프로토 타입에서는 멤버가 null이거나 정의되지 않은 것 같습니다.
Kev

그러나 이것은 아무도 그것을 깨뜨 리려고하지 않는 한만 작동합니다 – 만약 내가 설정 obj.userid = undefined하면 그것은 실패 할 것입니다 – 내 질문에 대한 마지막 편집을보십시오
Christoph

0

그것이 내려지는 것은 자바 스크립트의 동적 특성입니다.

나중에 추가 할 수 있도록 사물이 정의되지 않을 수 있습니다. 이것이 자바 스크립트가 강력하고 확장 가능한 이유입니다.


그리고 이것은 어떤 방식으로 내 질문과 관련이 있습니까?
Christoph

2
귀하의 질문에 답하기 때문에 관련성이 있습니다. 'null'은 '값이 없음'을 의미하는 '단일'정렬입니다. '정의되지 않음'은 무언가가 ... 충격적이라는 것을 말해줍니다. 저도 알아요 ... 정의되지 않았습니다. 완전히 다른 것입니다.
rfunduk

0

자바 스크립트의 이벤트 패러다임으로 프로그램을 래핑하면 중요한 언어 기능입니다.

// a key exists as a placeholder for something
if(obj[name] === null) 
// no key exists int eh hashtable that is in this object
if(obj[name] === undefined)

이것은 기본 동작을 나타 내기 위해 'nothing'을 사용하는 것과는 다른 동작을 나타 내기 위해 'nothing'을 나타내는 값이 필요한 데이터 집합을 다루는 경우 매우 유용합니다.

filter_func_pt = {
  date:function(d){ return Math.round(d.getTime()/1000);},
  user: null,
}

function transform(obj){
    var ret = {};
    for( var prop in obj){
       var f = filter_func_pt[prop];
       if(f)
          ret[prop] = f(obj);
       else if(filter_func_pt[prop] === null)
         continue;
       else
         ret[prop] == obj;
    }
  return ret;
}

var a = {
   date: new Date(),
   user: 'sam'
   votes: [23, 41, 55] 
};

var b = transform(a);

/* b = {
 *    date: 1298582417
 *    votes: [23, 41, 55]
 * }
 */

위의 코드에서 null 키워드와 정의되지 않은 서버는 매우 명확하고 다른 목적입니다. undefined 를 반환하는 filter_func_pt 객체에서 찾을 수없는 조회 는 반환 객체에 속성을있는 그대로 추가하는 것을 의미하는 반면, null 값은 값이 보류되어야하고 추가되지 않아야하며 여기에 참 값이 있음을 나타냅니다. case는 ret 객체에 값을 추가하기 전에 값을 변환하는 데 사용되는 함수를 나타냅니다 .


이 예는 인위적이며 약간 무의미합니다. Null은 의도를 전혀 밝히지 않고 오히려 마스킹합니다. 의미를 명확히하기 위해에서보다 명시적인 문자열을 사용할 수 있습니다. 예를 들어 '보류'또는 '스트립'과 같이 함수 유형에 대해 더 명확하게 파악하고 실제로 함수의 존재 여부를 확인할 수도 있습니다.
Eric Elliott

0

null은 아름답다

다른 모든 유형의 라이브 스크립트와 마찬가지로.

cite : JavaScript에는 기본적으로 '나는 존재하지 않습니다'라는 두 가지 값이 있습니다. 정의되지 않은 것과 null입니다.

왜 잘못된 말을하고 싶습니까?!

"null"" 0"이 "빈 숫자"인 것처럼 "빈 개체 " 입니다. 0은 아무것도 아니지만 숫자의 유형으로 존재합니다. null 은 물론 비어 있지만 "그것"이며 Object Type 의 잘 정의 된 것입니다 .

그렇지 않은 경우 이러한 것을 "유형"으로 말하는 것이 일반적입니다. 사실 그들은 "범주"입니다. 하지만 이제 끝났습니다.

그래서 "null"은 종류가없는 객체의 유형이라고 말할 것입니다. 그리고 "null"은 "나는 매우 많이 존재하지만 [!], 내 종류의 내용이 없습니다"라고 말합니다.

반면에 정의되지 않은 것은 유형과 종류 모두 부족 정의는 또한 유형 정의 될 일을. 정의되지 않은 유형의 유형은 고유 한 유형이됩니다. 일종의 [ "아무것도"존재하지 않으며 "아무것도"를 어떻게 정의합니까?] 질문입니다.

cite : 생성자 함수에서 정의되지 않거나 null이 반환 될 수 있습니다. 둘 다 빈 객체로 변환되기 때문입니다.

다시 한 번 잘못된 말을하셨습니다. 물론, "정의되지 않은"은 객체가 아니며 우리 인간이 이해하는 평범한 토큰입니다. 그러나 그 null 과 반대되는 것은-그리고 그것은 당신에게 말하고 있습니다 : 그것의 유형은 정확하지만 당신이 찾고있는 종류는 그 안에 포함되어 있지 않거나 적어도 현재는 아닙니다. 나중에 우리가 그것에 물건을 넣어 \ 할당 할 때 우리를 방문하십시오.

cite : 내가 생각할 수있는 유일한 차이점은 하나는 NaN으로 평가되고 다른 하나는 숫자 컨텍스트에서 0으로 평가된다는 것입니다.

이것이 핵심 구별의 요점을 설명합니다. undefined 는 일반 토큰이며 먼 친척과 동일한 '유전 적'물질로 구성되어 있으므로 [+ undefined] 연산은이를 다음과 같이 덕 변환합니다. NaN, 유사하게 null은 물론 올바른 종류의 0 \ Number로 변형되며, undefined 와는 반대로 문자열 (! 비어 있지 않습니다!)으로 변형되므로 대신 NaN 을 산출 합니다. 위치 : + undefined >> + "undefined">> NaN. 숫자 컨텍스트에는 명시적인 값이 필요하기 때문입니다.

부울 컨텍스트가 참조를 예상하는 동안-변환 할 항목을 찾지 못하고 'false'를 생성합니다.

이제 잘라 봅시다 ...

인용 : 다시 한 번 : 정의되지 않은 값과 null에 대한 개별 값의 실제 사용은 무엇입니까?

나는 당신에게 두 가지 경험적 예만을 제공하려고 노력할 것이며 충분하기를 바랍니다.

oElement.onclick >> null

// 의미-속성이 존재합니다. 예상되는 값은 Type : Object 이고 해당 oElement는 "onclick"이벤트를 지원합니다!

oElement.innerText >> ""

// means-속성이 존재합니다. 예상되는 값은 Type : String입니다 . 이는 oElement가 "innerText"속성을 지원함을 의미합니다.

두 경우 모두- "정의되지 않음"을 수신하면 속성이 존재하지 않음을 의미합니다. 지원되지 않거나 잘못된 (UA 공급 업체) 구현이 있습니다.

서리를 유지하고 재미있게 보내십시오.


게시물을 훼손하지 마십시오. 컨트 리뷰 션을 제거하려면이 댓글 바로 위에 있는 삭제 버튼을 사용하여 삭제 하십시오.
Michael Petrotta 2012 년

삭제 버튼은 없지만 보시면 클릭하세요!

0

undefined vs null에 대한 놀라운 토론을 읽은 후 Google에서 약간의 검색으로 Mozilla Documentations https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null로 이동 했습니다. 개체가 예상 될 수 있지만 관련 개체가없는 장소에서 검색됩니다.

Null 개체 패턴 https://en.wikipedia.org/wiki/Null_object_pattern 과 유사하지 않습니다.

그래서 이것이 Null 데이터 유형을 갖는 것이 합리적이라고 생각합니다.

typeof null // "object"로도 언급 된 문서 (레거시 이유로 "null"아님)

레거시 이유가 무엇인지 확실하지 않음

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