[javascript] 정의되지 않은 객체 속성 감지

JavaScript의 객체 속성이 올바른지 확인하는 가장 좋은 방법은 무엇입니까 undefined?



답변

속성 값이 특별한 값인지 확인하는 일반적인 방법 undefined은 다음과 같습니다.

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

객체에 실제로 이러한 속성이 없는지 확인 undefined하여 액세스하려고 할 때 기본적으로 반환 됩니다.

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

식별자와 연관된 값은 특수 값인지 확인하기 위해 undefined, 또는 그 식별자가 선언되지 않은 경우. 참고 :이 방법은 초기 오류없이 선언되지 않은 (참고 : 값을 갖는 것과는 다른 undefined) 식별자 를 참조하는 유일한 방법입니다 .

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

ECMAScript 5 이전의 JavaScript 버전에서는 전역 객체에서 “undefined”라는 속성을 쓸 foo === undefined수 있었으므로 실수로 재정의 된 경우 간단한 확인 이 예기치 않게 작동 할 수 있습니다. 최신 JavaScript에서이 속성은 읽기 전용입니다.

그러나 현대 JavaScript에서 “undefined”는 키워드가 아니므로 함수 내부의 변수 이름을 “undefined”로 지정하고 전역 속성을 숨길 수 있습니다.

이 경우에 대해 우려되는 경우 void 연산자 를 사용 하여 특수 undefined값 자체 를 얻을 수 있습니다.

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}


답변

이 주제에 대한 많은 잘못된 답변이 있다고 생각합니다. 일반적인 믿음과는 달리, “정의는” 하지 JavaScript의 키워드 실제로 값을 할당 할 수 있습니다.

올바른 코드

이 테스트를 수행하는 가장 강력한 방법은 다음과 같습니다.

if (typeof myVar === "undefined")

이것은 항상 올바른 결과를 반환하고 상황을 처리합니다. myVar 선언되지 않은 .

코드를 줄입니다. 사용하지 마세요.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

또한 myVar === undefinedmyVar가 선언되지 않은 상황에서 오류가 발생합니다.


답변

여기에 많은 다른 답변들에 의해 강력히 추천되었지만 typeof , 나쁜 선택 입니다. 변수에 값이 있는지 여부를 확인하는 데 사용해서는 안됩니다. 변수가 값 undefined과 변수가 있는지 여부를 종합적으로 검사 하는 역할을하기 때문 undefined입니다. 대부분의 경우 변수가 존재하는시기를 알고 typeof있으며 변수 이름이나 문자열 literal에 오타가 있으면 자동 실패 가능성이 나타납니다 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

따라서 기능 감지를 수행하지 않는 한 (예 typeof module !== 'undefined': CommonJS 환경에 특정한 코드의 단계로 확인하는 것과 같이) 지정된 이름이 범위 내에 있는지 확실하지 않은 경우 typeof변수에 사용될 때 해로운 선택이며 올바른 옵션은 다음과 같습니다. 값을 직접 비교하려면 :

var foo = …;

if (foo === undefined) {
    
}

이에 대한 몇 가지 일반적인 오해는 다음과 같습니다.

  • 에 “초기화되지 않은”변수 (읽는 것을 var foo() 또는 매개 변수 function bar(foo) { … }로 불리는 것은 bar()) 실패합니다. 이것은 명백한 사실이 아닙니다. 명시적인 초기화가없는 변수와 값이 주어지지 않은 매개 변수 undefined는 항상이고 항상 범위 내에 있습니다.

  • 그게 undefined덮어 쓸 수 있습니다. 이것에 더 많은 것이 있습니다. undefinedJavaScript의 키워드가 아닙니다. 대신, 정의되지 않은 값을 가진 전역 객체의 속성입니다. 그러나 ES5 이후로이 특성은 읽기 전용 이며 구성 할 수 없습니다 . 현대의 브라우저는 undefined속성을 변경할 수 없으며 2017 년 현재 오랫동안 그렇게되었습니다. 엄격한 모드의 부족은 undefined의 행동에도 영향을 미치지 않습니다 – 그냥 undefined = 5던지기 대신 아무 것도하지 않는 것과 같은 문장을 만듭니다 . 키워드가 아니기 때문에 name을 사용하여 변수를 선언 할 수 undefined있으며 해당 변수를 변경하여 다음과 같은 일반적인 패턴을 만들 수 있습니다.

    (function (undefined) {
        // …
    })()

    전역을 사용하는 것보다 위험합니다 undefined. 당신이 ES3와 호환 될 경우, 대신 undefinedvoid 0-에 의존하지 않습니다 typeof. ( void항상 피연산자에 대해 정의되지 않은 값으로 평가되는 단항 연산자였습니다.)

변수가 작동하지 않는 방식으로 실제 질문 인 객체 속성을 해결해야합니다. typeof객체 속성에 사용할 이유가 없습니다 . 기능 감지와 관련된 이전 예외는 여기에 적용되지 않습니다.typeof . 변수에 대한 특수 동작 만 있으며 개체 속성을 참조하는 식은 변수가 아닙니다.

이:

if (typeof foo.bar === 'undefined') {
    
}

입니다 항상 정확히 동등한 this³에 :

if (foo.bar === undefined) {
    
}

위의 조언을 고려하여 독자가 왜 사용하고 있는지 혼란스럽지 않게하기 위해 변수의 값을 나중에 확인하도록 리팩토링 할 수 있고 평범하기 때문에 평등을 확인 typeof하는 ===데 가장 적합하기 때문에 더 좋아 보인다, 당신은 항상 === undefined여기서도 ³ 를 사용해야한다 .

객체 속성과 관련하여 고려해야 할 사항은 실제로 확인하고 싶은지 여부 undefined입니다. 주어진 속성 이름은 객체에 없거나 ( undefined읽을 때 값을 생성 함) 값 과 함께 객체 자체 undefined에 존재 undefined하거나, 값과 함께 객체의 프로토 타입에 존재하거나, undefined값 이 아닌 객체에 존재 합니다. 'key' in obj키가 오브젝트의 프로토 타입 체인에 있는지 여부와 키가 오브젝트에 Object.prototype.hasOwnProperty.call(obj, 'key')직접 있는지 여부를 알려줍니다. 프로토 타입과 객체를 문자열 키 맵으로 사용하는 것에 대한이 답변에 대해서는 자세하게 설명하지 않겠습니다. 원래 질문에 대한 가능한 해석과 상관없이 다른 답변의 모든 나쁜 조언에 대항하기 때문입니다. 에 읽어더 많은 것을 위해 MDN의 객체 프로토 타입 !

¹ 예제 변수 이름의 특이한 선택? 이것은 Firefox 용 NoScript 확장 프로그램의 실제 죽은 코드입니다.
² 범위가 무엇인지 모르는 것이 일반적으로 괜찮다고 가정하지 마십시오. 다이나믹 스코프 남용으로 인한 보너스 취약점 : ES5 + 환경을 가정 하여 전역 객체 속성 나타내는 Project Zero 1225
³를 다시 한 번 . 그렇지 않으면 대체하십시오 .undefinedundefinedvoid 0


답변

JavaScript에는 null 이 있으며 정의되지 않았습니다 . 그들은 다른 의미를 가지고 있습니다.

  • 찾으시는 주소가 없습니다 는 변수 값이 의미합니다. 값이 무엇인지 알 수 없습니다.
  • null 은 변수 값이 정의되고 null로 설정됨을 의미합니다 (값 없음).

Marijn Haverbeke는 그의 무료 온라인 책 ” Eloquent JavaScript “(강조 광산)에서 다음과 같이 말합니다.

비슷한 의미의 null도 있는데,이 의미는 ‘이 값은 정의되어 있지만 값이 없습니다’입니다. undefined와 null의 의미 차이는 대부분 학문적이며 일반적으로 그리 흥미롭지 않습니다. 실제 프로그램에서는 종종 ‘가치’가 있는지 확인해야합니다. 이러한 경우, == undefined라는 표현식이 사용될 수 있는데, 이는 정확히 같은 값이 아니더라도 null == undefined가 true를 생성하기 때문입니다.

따라서 정의되지 않은 것이 있는지 확인하는 가장 좋은 방법은 다음과 같습니다.

if (something == undefined)

도움이 되었기를 바랍니다!

편집 : 편집에 대한 응답으로 객체 속성이 같은 방식으로 작동해야합니다.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined


답변

이것이 의미하는 것은 “undefined object property” ?

실제로 그것은 두 가지 다른 것을 의미 할 수 있습니다! 첫째, 그것은 의미 정의 적이 속성 둘째,이 의미는 개체 및 정의되지 않은 값을 갖는 속성 . 이 코드를 보자 :

var o = { a: undefined }

되어 o.a정의되지? 예! 그 값은 정의되어 있지 않습니다. 되어 o.b정의되지? 확실한! ‘b’속성이 전혀 없습니다! 두 상황에서 서로 다른 접근법이 어떻게 작동하는지 봅시다.

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

우리는 그것을 명확하게 볼 수 typeof obj.prop == 'undefined'있고 obj.prop === undefined동등하며, 그들은 서로 다른 상황을 구별하지 않습니다. 과'prop' in obj 속성이 전혀 정의되지 않았고 정의되지 않은 속성 값에주의를 기울이지 않는 상황을 감지 할 수 있습니다.

그래서 뭘 할건데?

1) 속성이 첫 번째 또는 두 번째 의미 (가장 일반적인 상황)에 의해 정의되지 않았는지 알고 싶습니다.

obj.prop === undefined // IMHO, see "final fight" below

2) 객체에 속성이 있고 그 값에 신경 쓰지 않는지 알고 싶습니다.

'prop' in obj

노트:

  • 객체와 그 속성을 동시에 확인할 수는 없습니다. 예를 들어 x가 정의되지 않은 경우이 값 x.a === undefinedtypeof x.a == 'undefined'증가 ReferenceError: x is not defined합니다.
  • 변수 undefined는 전역 변수이므로 실제로는window.undefined 브라우저에 있습니다). ECMAScript 1st Edition부터 지원되었으며 ECMAScript 5부터는 읽기 전용 입니다. 따라서 현대의 브라우저에서는 많은 저자가 우리를 놀라게하는 것을 좋아하므로 사실재정의 할 수 없지만 오래된 브라우저의 경우 여전히 그렇습니다.

마지막 싸움 : obj.prop === undefinedvstypeof obj.prop == 'undefined'

장점 obj.prop === undefined:

  • 조금 더 짧고 조금 더 예쁘게 보입니다
  • 철자가 틀리면 자바 스크립트 엔진에서 오류가 발생합니다. undefined

마이너스 obj.prop === undefined :

  • undefined 오래된 브라우저에서 재정의 가능

플러스 typeof obj.prop == 'undefined':

  • 정말 보편적입니다! 새롭고 오래된 브라우저에서 작동합니다.

마이너스 typeof obj.prop == 'undefined' :

  • 'undefned'( 철자가 틀렸다 난 그냥 그랬던 것처럼 당신이 그것을 맞춤법이 틀린 경우 자바 스크립트 엔진이 당신을 도울 수 있도록 여기에 단지 문자열 상수이다).

업데이트 (서버 측 JavaScript의 경우) :

Node.js는 전역 변수 undefined를 지원합니다 global.undefined( ‘global’접두어 없이도 사용할 수 있습니다). 서버 쪽 JavaScript의 다른 구현에 대해서는 모르겠습니다.


답변

이 문제는 다음 세 가지 사례로 요약됩니다.

  1. 개체에 속성이 있으며 값이 아닙니다 undefined.
  2. 객체에는 속성이 있으며 그 값은 undefined입니다.
  3. 개체에 속성이 없습니다.

이것은 내가 중요하다고 생각하는 것을 알려줍니다.

정의되지 않은 멤버와 정의되지 않은 값을 가진 정의 된 멤버간에 차이가 있습니다.

그러나 불행하게도 typeof obj.foo우리가 가지고있는 세 가지 경우를 알려주지 않습니다. 그러나 "foo" in obj사례를 구별하기 위해 이를 결합 할 수 있습니다 .

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

이 시험은 null출품작에 대해서도 동일하다는 점은 주목할 가치가 있습니다.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

나는 어떤 경우에는 속성이 있는지 여부를 확인하는 것보다 속성이 있는지 여부를 확인하는 것이 더 합리적이며 더 명확하다고 주장하며,이 확인이 다른 유일한 경우는 드문 경우입니다. 정의되지 않은 값을 가진 객체의 실제 항목

예를 들어, 방금 객체에 주어진 속성이 있는지 확인하는 많은 코드를 리팩토링했습니다.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

정의되지 않은 검사없이 작성되었을 때 더 명확했습니다.

if( "x" in blob ) { fn(blob.x); }

그러나 언급했듯이 이것들은 정확히 동일하지는 않습니다 (그러나 내 필요에 충분합니다).


답변

if ( typeof( something ) == "undefined") 

다른 사람들은 그렇지 않은 동안 이것은 나를 위해 일했습니다.