정의되지 않은 객체 속성을 탐지합니다
질문
JavaScript의 Object 속성이 정의되지 않은지 확인하는 가장 좋은 방법은 무엇입니까?
답변
속성의 값이 정의되지 않은 특수 값인지 확인하는 일반적인 방법은 다음과 같습니다.
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
객체가 실제로 이러한 속성을 가지고 있지 않은지 확인하려면 다음을 수행하려고 할 때 기본적으로 정의되지 않은 것으로 나타납니다.
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
식별자와 연결된 값이 정의되지 않은 특수 값이거나 해당 식별자가 선언되지 않은지 확인하려면 다음을 수행하십시오.
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
참고 :이 마지막 방법은 조기 오류없이 미확인 된 식별자를 참조하는 유일한 방법이며 정의되지 않은 값과 다릅니다.
ECMAScript 5 이전의 JavaScript 버전에서는 글로벌 객체에서 "undefined"라는 속성이 작성이 가능하므로 실수로 재정의 된 경우 예기치 않게 작동하지 않을 수 있습니다.현대 자바 스크립트 에서이 속성은 읽기 전용입니다.
그러나 현대 JavaScript에서 "undefined"는 키워드가 아니므로 기능 내부의 변수는 "정의되지 않은"이름을 지정하고 글로벌 속성을 섀도로 지정할 수 있습니다.
이 (unikedly) 가장자리 케이스에 대해 걱정하는 경우 무효 운영자를 사용하여 특별한 정의되지 않은 값 자체를 얻을 수 있습니다.
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
답변
이 주제에 대한 잘못된 답변이 많이 있음을 믿습니다.일반적인 믿음과는 달리 "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 === undefined는 myVar가 명시되지 않은 상황에서 오류가 발생합니다.
답변
여기서 많은 다른 답변에서 격렬하게 추천 했음에도 불구하고 TypeOf는 나쁜 선택입니다.변수가 정의되지 않은 값과 변수가 있는지 여부에 대한 결합 된 검사로 작동하기 때문에 변수가 정의되지 않은지 여부를 확인하는 데 사용해서는 안됩니다.대다수의 경우, 변수가 존재하는시기를 알고 있으며, TypeOf는 변수 이름이나 문자열 리터럴 '정의되지 않은'문자열에서 오타를 만드는 경우 TypeOf가 자동으로 실패 할 가능성을 소개합니다.
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!
}
따라서 기능 탐지 ²를 수행하지 않는 한, 주어진 이름이 범위에 있는지 여부 (commonjs 환경에 특정한 코드의 단계)로서 == '정의되지 않은 것과 같은 이름으로 =='정의되지 않은 것과 같은 불확실성이 있는지 여부에 관계없이, TypeOf는 사용할 때 유해한 선택입니다.변수에서 올바른 옵션은 값을 직접 비교하는 것입니다.
var foo = …;
if (foo === undefined) {
⋮
}
이에 대한 일반적인 오해는 다음과 같습니다.
막대 ()로 호출 된 "초기화되지 않은"변수 (var foo) 또는 매개 변수 (함수 바 (foo) {...})를 읽는 것은 실패합니다.이것은 단순히 해당되지 않습니다 - 명시 적 초기화가없는 변수와 값이 지정되지 않은 매개 변수는 항상 정의되지 않으며 항상 범위가 아닙니다. 정의되지 않은 것은 덮어 쓸 수 있습니다.정의되지 않은 키워드는 아니지만 읽기 전용이며 구성 할 수 없습니다.비 키워드 상태 (개체, 수학, Nan ...)와 실제 코드가 일반적으로 적극적으로 악의적 인 환경으로 작성되지 않아도 실용적인 코드가 발생하지 않으면 다른 내장이 있습니다. 그래서 이것은 좋은 이유가 아닙니다.undefined에 대해 걱정했다.(그러나 코드 생성기를 작성하는 경우 공백 0을 자유롭게 사용할 수 있습니다.)
변수가 어떻게 작동하는 방식으로 실제 질문을 해결할 시간입니다. 객체 속성.객체 속성에 대해 TypeOf를 사용하는 이유가 없습니다.기능 탐지에 관한 이전 예외는 여기에 적용되지 않습니다. TypeOf는 변수에 대한 특별한 동작 만 있으며, 객체 속성이 변수가 아닌 표현식입니다.
이:
if (typeof foo.bar === 'undefined') {
⋮
}
항상 이에 정확히 같습니다.
if (foo.bar === undefined) {
⋮
}
그리고 위의 조언을 고려한 이유를 사용하는 이유를 고려하기 위해 === 늦게 변수의 가치를 검사하는 것으로 refactores를 사용하기 때문에 ===을 사용하는 것이 왜 ===을 사용하는 이유를 사용하는 이유가 있기 때문에 독자를 혼란스럽게하는 것을 방지합니다.평범한 것만으로 더 잘 보이기 때문에 항상 === undefinedă니다.
객체 속성에 관해서 고려해야 할 사항은 정말로 정의되지 않은 것을 정말로 확인하고 싶은지 여부입니다.주어진 속성 이름은 객체에 결석 할 수 있습니다 (읽을 때 정의되지 않은 값 생성).값.OBJ의 'Key'는 객체의 프로토 타입 체인의 키가 어디서나 키가 있는지 여부를 알려줍니다. object.prototype.hasownproperty.call (obj, 'key')은 객체에 직접 있는지 여부를 알려줍니다.나는 프로토 타입에 대한이 답변 에서이 답변에 대해 자세히 가지 않을 것이고, 그럼에도 불구하고, 원래의 질문에 대한 가능한 해석에 관계없이 다른 답변의 모든 나쁜 조언에 대해서는 대부분의 모든 나쁜 조언을 카운터링하려는 것으로 인정되기 때문입니다.MDN에서 객체 프로토 타입을 읽으십시오!
✔ 예시적인 변수 이름의 비정상적인 선택?이것은 Firefox의 Noscript 확장자의 실제 코드입니다. ² 일반적으로 범위에있는 것을 알지 못한다고 가정하지 마십시오.동적 범위의 학대로 인한 보너스 취약점 : 프로젝트 제로 1225 ❏ 다시 ES5 + 환경을 가정하고 정의되지 않은 것은 전역 객체의 정의되지 않은 속성을 나타냅니다.
답변
자바 스크립트에서는 null이 있고 정의되지 않았습니다.그들은 다른 의미를 가지고 있습니다.
정의되지 않은 것은 변수 값이 정의되지 않았 음을 의미합니다.가치가 무엇인지 알려지지 않았습니다. NULL은 변수 값이 정의되고 null (값이 없음)로 설정되었음을 의미합니다.
Marijn Haverbeke는 무료 온라인 책 "Eloquent Javascript"(강조 광산) :
유사한 값이 있으며, NULL은 '이 값이 정의되어 있지만 값이없는 것'입니다.정의되지 않은과 널 사이의 의미의 차이는 대부분 학문적이며 대개 매우 흥미롭지 않습니다.실용적인 프로그램에서는 '값이 있는지 여부를 확인해야합니다.이 경우, == undefined 표현은 정확히 동일한 값이 아니더라도 null == undefined가 true를 생성 할 수 있기 때문입니다.
그래서, 무언가가 정의되지 않은지 확인하는 가장 좋은 방법은 다음과 같습니다.
if (something == undefined)
객체 속성은 동일한 방식으로 작동해야합니다.
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
답변
이는 무엇을 의미합니까? "정의되지 않은 객체 속성"?
실제로 그것은 두 가지 아주 다른 것을 의미 할 수 있습니다!첫째, 객체에 정의되지 않은 속성과 두 번째로 정의되지 않은 값이있는 속성을 의미 할 수 있습니다.이 코드를 살펴 보겠습니다.
var o = { a: undefined }
o.a undefined입니까?네!그 값은 정의되지 않습니다.o.b undefined입니까?확신하는!'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
우리는 obj.prop == 'undefined'와 obj.prop === undefined가 해당하는 것을 분명히 볼 수 있습니다. 해당 다른 상황을 구별하지는 않습니다.obj의 'prop'은 재산이 전혀 정의되지 않았으며 정의되지 않은 속성 값에주의를 기울이지 않을 때 상황을 감지 할 수 있습니다.
그래서 뭐 할까?
1) 재산이 첫 번째 또는 두 번째 의미 (가장 일반적인 상황)에 의해 정의되지 않은지 알고 싶습니다.
obj.prop === undefined // IMHO, see "final fight" below
2) 객체가 일부 재산이 있는지 여부를 알고 싶습니다.
'prop' in obj
메모:
객체와 해당 속성을 동시에 확인할 수 없습니다.예를 들어,이 x.a === 정의되지 않았 거나이 TypeOf x.a == '정의되지 않은'ReferenceError : X가 정의되지 않은 경우 x가 정의되지 않습니다. 변수 undefined는 전역 변수입니다 (그래서 실제로 브라우저에서 윈도우입니다.).ECMAScript 첫 번째 버전 이후에 지원되었으며 ECMAScript 5는 읽기 전용입니다.따라서 현대적인 브라우저에서는 많은 저자가 우리를 두려워하는 것을 좋아하는 것처럼 진실로 재정의 할 수는 없지만 이것은 여전히 구형 브라우저에서는 여전히 사실입니다.
최종 싸움 : obj.prop === undefined vs typeOf obj.prop == 'undefined'
obj.prop === undefined의 플러스 :
그것은 조금 더 짧고 조금 더 예쁘게 보입니다. JavaScript 엔진이 undefined를 철회 한 경우 오류가 발생합니다.
obj.prop === undefined :
undefined는 오래된 브라우저에서 무시 될 수 있습니다
obj.prop == 'undefined'의 플러스 :
그것은 정말로 보편적입니다!새롭고 오래된 브라우저에서 작동합니다.
obj.prop == 'undefined'의 빼기 :
'undefined'(철자가 틀린) 여기서 문자열 일정 일 뿐이므로 JavaScript 엔진이 방금 한 것처럼 철자를 틀 셨다면 도움이되지 않습니다.
업데이트 (서버 측 JavaScript의 경우) :
node.js는 global.undefined로 정의되지 않은 전역 변수를 지원합니다 ( '전역'접두사 없이도 사용할 수 있음).서버 측 JavaScript의 다른 구현에 대해 모르겠습니다.
답변
이 문제는 3 가지 경우까지 끓습니다.
- The object has the property and its value is not
undefined
. - The object has the property and its value is
undefined
. - The object does not have the property.
이것은 내가 중요한 것을 고려하는 것을 알려줍니다.
정의되지 않은 멤버와 정의되지 않은 값이있는 정의 된 멤버는 정의되지 않습니다.
그러나 불행하게 obj.foo는 우리가 가진 세 사례 중 어떤 것을 알려주지 않습니다.그러나 우리는 이것을 obj의 "foo"와 결합하여 사례를 구별 할 수 있습니다.
| 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
어떤 경우에는 그 속성이 정의되지 않았는지 여부를 확인하는 것보다 더 의미가 있는지 확인하는 것이 더 의미가 있으며이 수표가 다르게되는 유일한 경우는 사례 2이며 희귀 한 경우undefined 값이있는 객체의 실제 항목입니다.
예를 들면 다음과 같이 : 객체가 주어진 속성이 있는지 여부를 수표가있는 코드가있는 코드를 requactoring했습니다.
if( typeof blob.x != 'undefined' ) { fn(blob.x); }
정의되지 않은 상태에서 확인할 때는 더 명확 해졌습니다.
if( "x" in blob ) { fn(blob.x); }
그러나 언급 된 바와 같이 정확히 동일하지는 않습니다 (그러나 내 필요에 충분히 좋지만 더 좋은 것).
출처:https://stackoverflow.com/questions/27509/detecting-an-undefined-object-property
최근댓글