我今天发现这是为了检查某物是否为布尔值:
代替:
typeof a === 'boolean' && //do sth
您可以使用:
a === !!a && //do sth
还有其他类似方法可以检查typeof string/number/obj/arr
等吗?
我不是在寻找最佳实践,而是在寻找进行“类型检查”的巧妙方法。
答案 0 :(得分:2)
javascript中的类型并不是那么简单,但是this是您的理想指南!
用Java语言检查类型很麻烦。
typeof运算符
开始时有typeof。这个方便的运算符给您 Javascript值的“类型”:
typeof 3 // "number"
typeof "abc" // "string"
typeof {} // "object"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
一切都很好,直到...
typeof [] // "object"
嗯?数组的类型是对象?我想是的,如果你想得到 关于它的技术性,但是...
typeof null // "object"
好的,现在这是错误的!
运算符实例
instanceof运算符告诉您是否有对象 是某种类型的实例。所谓“类型”是指 构造函数。例如
function Animal(){}
var a = new Animal()
a instanceof Animal // true
instanceof的跨窗口问题
事实证明instanceof还有另一个问题。它分解的时候 您尝试测试来自另一个窗口的对象。你懂?的 为每个或弹出窗口创建的 您创建的。
var iframe = document.createElement('iframe')
document.body.appendChild(iframe)
var iWindow = iframe.contentWindow // get a reference to the window object of the iframe
iWindow.document.write('<script>var arr = [1, 2, 3]</script>') // create an array var in iframe's window
iWindow.arr // [1, 2, 3]
iWindow.arr instanceof Array // false
鸭型
由于typeof或instanceof都不令人满意,因此许多求助于 鸭打字。这意味着检查行为:如果它看起来像鸭子 像鸭子一样嘎嘎叫,就我而言,它就是鸭子。 可以肯定的是,我误报了……哦。
因此,使用鸭子类型,isArray检查可能看起来像
// source: http://forums.devshed.com/javascript-development-115/javascript-test-whether-a-variable-is-array-or-not-33051.html
function isArray(obj){
return (typeof(obj.length)=="undefined") ?
false:true;
}
Object.prototype.toString方法
事实证明,您可以通过以下方式获取有关对象的类型信息: 使用Object.prototype.toString方法。
Object.prototype.toString.call(3) // "[object Number]"
Object.prototype.toString.call([1, 2, 3]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"
Function.prototype.toString方法
另一种测试类型信息的方法是使用 Function.prototype.toString方法。
Function.prototype.toString.call((3).constructor)
// "function Number() {
// [native code]
// }"
DOM元素和主机对象
到目前为止,我还没有提到DOM元素和主机的类型检查 对象。那是因为很难。除了鸭式打字, 上面提到的所有方法都不适用于所有浏览器。如果你 删除IE7及以下版本,但是,您实际上可以获得一些东西 去工作。下面的输出是使用Tutti创建的
var div = document.createElement('div')
typeof div
Safari 5.0 => object
Firefox 3.6 => object
IE 7.0 => object
IE 8.0 => object
Opera 11.01 => object
div instanceof Element
Safari 5.0 => true
Firefox 3.6 => true
IE 7.0 => Error: 'Element' is undefined
IE 8.0 => true
Opera 11.01 => true
div instanceof HTMLDivElement
Safari 5.0 => true
Firefox 3.6 => true
IE 8.0 => true
IE 7.0 => Error: 'HTMLDivElement' is undefined
Opera 11.01 => true
答案 1 :(得分:1)
一个非常相似的概念适用于所有基本类型,但是涉及到函数调用,并且可能不仅仅像布尔示例那样进行布尔求反:
// String
a === String(a)
// Number
n === +n // **FAILS** if `a` is `NaN` (which is `typeof "number"`)
Object.is(n, +n) // Works even if it is, but 0 and -0 are considered different
// Object (including arrays)
o === Object(o)
最后一个有效的原因是,Object
返回调用对象的对象(如果您使用对象调用它(不会创建新对象))。
我知道您已经说过您对技巧而不是最佳实践感兴趣,但是...总的来说,我不会做上述事情。如果我关心类型但不知道它是什么,我会使用typeof
;如果我想要特定的目标类型并且不知道输入是什么类型,我会使用转换。
答案 2 :(得分:0)
您无法做到干净。我发现Javascript有一些古怪之处,即使是最丰富的经验,也几乎总是会让人失望。通常,您最终会得到非常丑陋的,不是真正人类可读的条件语句:
if (
typeof foo !== 'string'
|| (typeof foo !== 'number'
|| (typeof foo === 'number' && !isNaN(chk)))
|| !Array.isArray(chk)
) {
throw Error("Not valid, but I don't know why.")
}
您应该考虑使用一个很小的库,例如Not。解决所有问题:
let integer = 10
let array = []
not('number', 10) // returns false
not('number', []) // throws error
如果养成习惯,您的代码将更加强大。 Typescript解决了部分问题,但在运行时不起作用,这也很重要。
function test (string, boolean) {
// any of these below will throw errors to protect you
not('string', string)
not('boolean', boolean)
// continue with your code.
}