JavaScript의 Typeof는 실제로 많은 작업에 사용될 수 있지만 이상한 동작도 많이 합니다. 이 문서에서는 다양한 용도를 나열하고 기존 문제와 해결 방법도 지적합니다.
이 글을 읽는 전제는 이제 원시값과 객체값의 차이를 알아야 한다는 것입니다.
변수가 존재하는지, 값이 있는지 확인
typeof는 두 가지 경우에 "정의되지 않음"을 반환합니다.
변수가 선언되지 않았습니다
변수의 값이 정의되지 않았습니다
예:
> 선언되지 않은 변수 유형 === "정의되지 않음"
> var 선언된 변수
> 🎜>'undefine'
> typeof undefine
'undefine'
값이 정의되지 않았는지 여부를 감지하는 다른 방법이 있습니다.
> var value = undefine;
> value === undefine
true
그러나 이 방법을 사용하는 경우 선언되지 않은 변수에 있는 경우 예외가 발생합니다. 왜냐하면 typeof만이 일반적으로 오류 보고 없이 선언되지 않은 변수를 감지할 수 있기 때문입니다.
>
ReferenceError: undeclaredVariable이 정의되지 않았습니다참고: 초기화되지 않은 변수, 매개 변수로 전달되지 않은 형식 매개 변수 및 존재하지 않는 속성은 항상 액세스 가능하므로 위의 문제가 발생하지 않습니다. 값은 다음과 같습니다. 항상 정의되지 않음: > var 선언된 변수;> 선언된 변수 === 정의되지 않음true > (함수 (x) { return x === 정의되지 않음 }())true > 정의되지 않음true번역자 참고 사항: 따라서 선언되지 않은 전역 변수의 존재를 검색하려면 if(window.maybeUndeclaredVariable){}를 사용할 수도 있습니다. 문제: typeof가 이러한 작업을 완료할 때 매우 복잡해 보입니다. 해결 방법: 이러한 작업은 흔하지 않기 때문에 일부 사람들은 더 나은 솔루션을 찾을 필요가 없습니다. 하지만 누군가가 특별한 연산자를 제안할 수도 있습니다: > 🎜>> 선언된 변수
false
또는 변수가 선언되었는지 감지하기 위해 연산자가 필요할 수도 있습니다.
> ; 선언되지 않은 변수
false
> 선언된 변수
true
번역자 주: Perl에서 위에 정의된 연산자는 Defined()와 동일하고, 위에서 선언된 연산자는 presents()와 동일합니다. 값이 정의되지 않음 또는 null이 아닌지 확인질문: 값이 정의되었는지 여부를 감지하려는 경우(값이 정의되지 않음 또는 null이 아님) ), 그런 다음 typeof의 가장 유명한 이상한 표현 중 하나를 발견했습니다(버그로 간주됨): typeof null은 "object"를 반환합니다: > typeof null ' object'역자 주: 이는 원래 JavaScript 구현의 버그라고만 말할 수 있으며 이것이 현재 표준이 규제되는 방식입니다. V8은 한때 null === "null" 유형을 수정하고 구현했지만 결국 실행 불가능하다는 것이 입증되었습니다. http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null. (주석: typeof는 null에서 작동할 때 "객체"를 반환합니다. 이는 JavaScript 언어 자체의 버그입니다. 안타깝게도 이 버그는 기존 버그가 너무 많기 때문에 절대 수정되지 않습니다. 코드는 이미 이 동작에 의존합니다. 그러나 null이 객체입니까? stackoverflow에 이 문제에 대한 토론이 있습니다: http://stackoverflow.com/questions/801032/null-object-in-javascript/7968470#7968470 @justjavac) 🎜>
해결책: 이 작업을 수행하려면 typeof를 사용하지 말고 대신 다음 함수를 사용하십시오.
function isDefined( x) {
return x !== null && x !== undefine;
}
또 다른 가능성은 myValue가 정의되지 않은 경우 다음 표현식에서 "기본값 연산자"를 도입하는 것입니다. defaultValue를 반환합니다:
myValue ?? defaultValue
위 표현식은 다음과 같습니다.
(myValue !== 정의되지 않은 && myValue !== null) ? myValue : defaultValue
또는:
myValue ??= defaultValue
는 실제로 다음을 단순화한 것입니다. 명령문:
myValue = myValue ?? defaultValue
bar와 같은 중첩 속성에 액세스할 때 다음 연산자의 도움이 필요할 수 있습니다.
obj.foo.bar
obj 또는 obj.foo가 정의되지 않은 경우 위 표현식에서는 예외가 발생합니다. 연산자.??를 사용하면 위 표현식이 레이어별로 속성을 탐색할 때 값이 정의되지 않거나 null인 첫 번째 발견된 속성을 반환할 수 있습니다.
obj .??foo.??bar
위 표현식은 다음과 동일합니다:
(obj === 정의되지 않음 || obj === null) ?
: (obj.foo === 정의되지 않음 || obj.foo === null) ? obj.foo
: obj.foo.bar
는 객체 값을 구별합니다. 및 기본 값
다음 함수는 x가 객체 값인지 확인하는 데 사용됩니다.
function isObject(x) {
return (typeof x === "function"
|| (typeof x === "object" && x !== null));
}
문제: 위 이는 typeof가 함수와 객체를 다른 유형으로 취급하고 typeof null이 "객체"를 반환하기 때문입니다.
해결 방법: 객체 값을 감지하는 데에도 종종 사용되는 방법이 있습니다. :
function isObject2(x) {
return x === Object(x);
}
경고: 여기서는 object를 감지하는 데 사용할 수 있다고 생각할 수도 있지만, object의 프로토타입을 사용하여 인스턴스 관계를 결정합니다. 따라서 프로토타입이 없는 개체는 어떻게 해야 할까요?
> obj = Object.create(null);
> Object.getPrototypeOf(obj)
null
obj는 실제로 객체이지만 어떤 인스턴스도 아닙니다. 값:
> obj 유형
'객체'
> obj 인스턴스
false
실제로는 그러한 개체를 거의 접하지 못할 수 있지만 존재하며 목적이 있습니다.
번역자 주: Object.prototype은 프로토타입이 없는 유일한 내장 개체입니다.
>Object.getPrototypeOf(Object.prototype)
null
>typeof Object.prototype
'객체'
>Object.prototype instanceof Object
false
기본 값의 유형은 무엇입니까?
typeof는 기본 값 유형을 보는 데 가장 적합합니다. .
> typeof "abc"
'문자열'
> 정의되지 않음
'정의되지 않음'
문제: null 유형의 이상한 동작을 알고 있어야 합니다.
> typeof null // 조심하세요!
'object'
해결 방법: 다음 함수를 사용하면 이 문제를 해결할 수 있습니다(이 용도로만 사용). 사례).
function getPrimitiveTypeName(x) {
var typeName = typeof x;
switch(typeName) {
케이스 "정의되지 않음 ":
케이스 "부울":
케이스 "번호":
케이스 "문자열":
return typeName;
사례 "객체":
if (x === null) {
~ > | "+x);
}
}
더 나은 솔루션 해결책: 원래 값의 유형을 반환하는 것 외에도 getTypeName() 함수를 구현합니다. 객체 값의 내부 [[클래스]] 속성을 반환합니다. 이 함수를 구현하는 방법은 다음과 같습니다(역자 주: jQuery의 $.type이 그러한 구현입니다)
특정 값이 함수인지
typeof를 사용할 수 있습니다. 값이 함수인지 테스트합니다.
> typeof 함수() {}
'function'
> typeof Object.prototype.toString
' function'
원칙적으로 instanceof Function도 이 요구 사항을 감지할 수 있습니다. 언뜻 보면 글쓰기 방식이 더 우아해 보이는 것 같습니다. 그러나 브라우저에는 특이한 점이 있습니다. 모든 프레임과 창에는 자체 전역 변수가 있습니다. 따라서 한 프레임에서 다른 프레임으로 객체를 전달하는 경우 두 프레임의 생성자가 다르기 때문에 인스턴스가 제대로 작동하지 않습니다. 이것이 ECMAScript5에 Array.isArray() 메소드가 있는 이유입니다. 객체가 주어진 생성자의 인스턴스인지 여부를 확인하는 프레임워크 간 방법이 있다면 좋을 것입니다. 위의 getTypeName()은 사용 가능한 해결 방법이지만 보다 근본적인 해결 방법이 있을 수 있습니다.
개요
언급된 다음은 현재 JavaScript에서 가장 시급한 요구사항이며 typeof가 현재 담당하는 기능적 특징 중 일부를 대체할 수 있습니다.
isDefined()(예: Object.isDefined()): 함수 또는 연산자로 사용할 수 있습니다.
isObject()
getTypeName()
객체가 지정된 생성자의 인스턴스인지 여부를 감지하는 프레임워크 간 메커니즘
특정 변수가 선언되었는지 여부를 확인하십시오. 자체 연산자가 필요하지 않을 수도 있습니다.