Home >Web Front-end >JS Tutorial >Summary of usage of typeof in js_javascript skills

Summary of usage of typeof in js_javascript skills

WBOY
WBOYOriginal
2016-05-16 17:09:41982browse

JavaScript中的typeof其实非常复杂,它可以用来做很多事情,但同时也有很多怪异的表现.本文列举出了它的多个用法,而且还指出了存在的问题以及解决办法.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Ftypeof

    > typeof undefined
    'undefined'
    > typeof null // well-known bug
    'object'
    > typeof true
    'boolean'
    > typeof 123
    'number'
    > typeof "abc"
    'string'
    > typeof function() {}
    'function'
    > typeof {}
    'object'
    > typeof []
    'object'
    > typeof unknownVariable
    'undefined'

1.检查一个变量是否存在,是否有值.
typeof在两种情况下会返回"undefined":一个变量没有被声明的时候,和一个变量的值是undefined的时候.例如:

> typeof undeclaredVariable === "undefined" true > var declaredVariable; > typeof declaredVariable 'undefined' > typeof undefined 'undefined'
还有其他办法检测某个值是否是undefined:

> var value = undefined; > value === undefined true
但这种方法如果使用在一个未声明的变量上的时候,就会抛出异常,因为只有typeof才可以正常检测未声明的变量的同时还不报错:

> undeclaredVariable === undefined ReferenceError: undeclaredVariable is not defined
注意:未初始化的变量,没有被传入参数的形参,不存在的属性,都不会出现上面的问题,因为它们总是可访问的,值总是undefined:

> var declaredVariable; > declaredVariable === undefined true > (function (x) { return x === undefined }()) true > ({}).foo === undefined true
译者注:因此,如果想检测一个可能没有被声明的全局变量是否存在,也可以使用 if(window.maybeUndeclaredVariable){}


问题: typeof在完成这样的任务时显得很繁杂.

解决办法: 这样的操作不是很常见,所以有人觉的没必要再找更好的解决办法了.不过也许有人会提出一个专门的操作符:

> defined undeclaredVariable false > var declaredVariable; > defined declaredVariable false
或者,也许有人还需要一个检测变量是否被声明的操作符:

> declared undeclaredVariable false > var declaredVariable; > declared declaredVariable true
译者注:在perl里,上面的defined操作符相当于defined(),上面的declared操作符相当于exists(),

2.判断一个值不等于undefined也不等于null
问题:如果你想检测一个值是否被定义过(值不是undefined也不是null),那么你就遇到了typeof最有名的一个怪异表现(被认为是一个bug):typeof null返回了"object":

> typeof null 'object'
译者注:这只能说是最初的JavaScript实现的bug,而现在标准就是这样规范的.V8曾经修正并实现过typeof null === "null",但最终证明不可行.http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null


解决办法: 不要使用typeof来做这项任务,用下面这样的函数来代替:

function isDefined(x) { return x !== null && x !== undefined; }
另一个可能性是引入一个“默认值运算符”,在myValue未定义的情况下,下面的表达式会返回defaultValue:

myValue ?? defaultValue
上面的表达式等价于:

(myValue !== undefined && myValue !== null) ? myValue : defaultValue
又或者:

myValue ??= defaultValue
其实是下面这条语句的简化:

myValue = myValue ?? defaultValue
当你访问一个嵌套的属性时,比如bar,你或许会需要这个运算符的帮助:

obj.foo.bar
如果obj或者obj.foo是未定义的,上面的表达式会抛出异常.一个运算符.??可以让上面的表达式在遍历一层一层的属性时,返回第一个遇到的值为undefined或null的属性:

obj.??foo.??bar
上面的表达式等价于:

(obj === undefined || obj === null) ? obj : (obj.foo === undefined || obj.foo === null) ? obj.foo : obj.foo.bar

3. 객체 값과 원시 값 구별 ​
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를 사용할 수 있다고 생각할 수도 있지만, object의 프로토타입을 사용하여 인스턴스 관계를 결정합니다. 예, 프로토타입 없이 객체를 어떻게 처리해야 할까요?

> var obj = Object.create(null); > Object.getPrototypeOf(obj) null
obj는 실제로 객체이지만 어떤 값의 인스턴스도 아닙니다.

> typeof obj 'object' > obj instanceof Object false
실제로는 이러한 객체가 거의 발생하지 않지만 존재하고 목적이 있습니다.

번역자 주: Object.prototype은 기본적으로 존재하는 객체이며 프로토타입이 없습니다

>Object.getPrototypeOf(Object.prototype)null>typeof Object.prototype'object'>Object.prototype instanceof Object false

4. 원시값의 유형은 무엇인가요?
typeof는 원시값의 유형을 확인하는 가장 좋은 방법입니다.

> typeof "abc" 'string' > typeof undefine 'undefine'
문제: typeof null의 이상한 동작을 알고 있어야 합니다.

> typeof null // 주의하세요! 'object'
해결책: 다음 함수로 이 문제를 해결할 수 있습니다(이 사용 사례에만 해당).

function getPrimitiveTypeName(x) { var typeName = typeof x; switch(typeName) { 케이스 "정의되지 않음": 케이스 "부울": 케이스 "문자열": 케이스 "객체": if ( x === null) { return "null"; } default: // 전달된 이전 판단 중 없음 new TypeError("매개변수가 기본 값이 아닙니다: " x) }

더 나은 해결책 방법: 원래 값의 유형을 반환하는 것 외에도 객체 값의 내부 [[Class]] 속성을 반환할 수 있는 함수 getTypeName()을 구현합니다. 이 함수를 구현하는 방법은 다음과 같습니다(번역자 참고 사항: $. jQuery로 입력하면 이렇게 구현됩니다)

5. 값이 함수인지 여부
typeof를 사용하면 값이 함수인지 확인할 수 있습니다.> > typeof Object.prototype.toString 'function'

원칙적으로는 instanceof Function도 이 요구 사항을 감지할 수 있습니다. 언뜻 보기에는 작성 방법이 더 우아해 보입니다. 모든 프레임과 창에는 자체 전역 변수가 있습니다. 따라서 한 프레임에서 다른 프레임으로 객체를 전달하면 두 프레임의 생성자가 다르기 때문에 인스턴스가 제대로 작동하지 않습니다. 이것이 바로 Array.isArray가 있는 이유입니다. () 객체가 특정 생성자의 인스턴스인지 확인하는 프레임워크 간 방법이 있으면 좋을 것입니다. 위의 getTypeName()은 해결 방법이 있지만 더 근본적인 해결책이 있을 수도 있습니다. 🎜>

6. 개요
다음은 현재 JavaScript에서 가장 시급한 요구사항이며 typeof의 현재 책임 중 일부 기능을 대체할 수 있습니다.

isDefined()(예: Object.isDefined()): 함수 또는 연산자로 사용할 수 있습니다.

isObject()
getTypeName()
크로스 프레임이 가능하고 객체가 다음과 같은지 감지합니다. 지정됨 생성자 인스턴스
의 메커니즘은 변수가 선언되었는지 여부를 확인합니다. 이러한 요구 사항은 자체 연산자를 가질 필요가 없을 수도 있습니다.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn