ホームページ >ウェブフロントエンド >jsチュートリアル >js_javascript スキルにおける typeof の使用法の概要

js_javascript スキルにおける typeof の使用法の概要

WBOY
WBOYオリジナル
2016-05-16 17:09:41984ブラウズ

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. Distinguish between object values ​​and primitive values ​​
The following function is used to detect whether x is an object value:

function isObject(x) { return (typeof x === "function" || (typeof x === "object" && x !== null)); }
Problem: The above detection is more complicated , because typeof regards functions and objects as different types, and typeof null returns "object".

Solution: The following method is also often used to detect object values:

function isObject2(x) { return x === Object(x); }
Warning: You may think that you can use instanceof Object to detect it, but instanceof determines the instance relationship by using the prototype of an object. Yes, what to do with objects without prototypes:

> var obj = Object.create(null); > Object.getPrototypeOf(obj) null
obj is indeed an object, but it is not an instance of any value:

> typeof obj 'object' > obj instanceof Object false
In practice, you may rarely encounter such an object, but it does exist and has its purpose.

Translator’s Note: Object.prototype is an object that exists by default and has no prototype

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

4. What is the type of a primitive value?
typeof is the best way to check the type of a primitive value.

> typeof "abc" 'string' > typeof undefined 'undefined'
Problem: You must be aware of the weird behavior of typeof null.

> typeof null // Be careful! 'object'
Solution: The following function can fix this problem (only for this use case).

function getPrimitiveTypeName(x) { var typeName = typeof x; switch(typeName) { case "undefined": case "boolean": case "number": case "string": return typeName; case "object": if ( x === null) { return "null"; } default: // None of the previous judgments passed throw new TypeError("The parameter is not a primitive value: " x); } }

Better solution Method: Implement a function getTypeName(), which in addition to returning the type of the original value, can also return the internal [[Class]] attribute of the object value. Here is how to implement this function (Translator's Note: $.type in jQuery This is how it is implemented)

5. Whether a value is a function
typeof can be used to detect whether a value is a function.> typeof function () {} 'function' > typeof Object.prototype.toString 'function'

In principle, instanceof Function can also detect this requirement. At first glance, it seems that the writing method is more elegant. However, the browser has a quirk: every Both frames and windows have their own global variables. So if you pass an object from one frame to another, instanceof won't work properly because the two frames have different constructors. This is why There is a reason why there is Array.isArray() method in ECMAScript5. It would be nice if there was a cross-framework method for checking whether an object is an instance of a given constructor. The above getTypeName() is A workaround available, but maybe there's a more fundamental solution.

6. Overview
The following mentioned should be the most urgent needs in JavaScript at present, and can replace some of the functional features of typeof’s current responsibilities:

isDefined() (such as Object.isDefined()): can be used as a function or an operator
isObject()
getTypeName()
Can cross-frame, detect whether an object is specified The mechanism of the constructor instance
checks whether a variable has been declared. Such a requirement may not be necessary to have its own operator.

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。