理论上来说js中类型判断是一个不靠谱的东西。 通常用作类型判断的方法:instanceoftypeof

typeof

返回一个字符串,用来说明变量的数据类型. 返回结果:number, boolean, string, function, object, undefined 通常用typeof判断一个对象是否存在:

if(typeof a != 'undefined'){
    // do something
}
if(a){
    // do something
    // a 不存在可能报错
}

局限性: Array,Null等特殊对象使用typeof一律返回object,这个很坑爹。

instanceof

用来判断一个变量是否属于某个对象的实例。

a instanceof b ? console.log("true") : console.log("false");
let a = [1, 2, 3];
console.log(a instanceof Object); // true
console.log(a instanceof Array); // true

上面的例子中a instanceof Objecta instanceof Array都是true,这是因为ArrayObject的子类.

其他的类型判断

使用contructor判断

[1, 2].__proto__.constructor === Array; // true
[1, 2].__proto__.constructor === Object; // false
"str".__proto__.constructor === String; // true
true.__proto__.constructor === Boolean; // true
window.testF = function(){console.log("testF")}; // 函数
testF.__proto__.constructor === Function; // true
window.testF2 = ()=>console.log('testF2'); // 函数表达式
testF2.__proto__.constructor === Function; // true
NaN.__proto__.constructor === Number; // true
1.__proto__; // Uncaught SyntaxError: Invalid or unexpected token
{"a":1}.__proto__;// Uncaught SyntaxError: Unexpected token ':'

使用Object.prototype.toString.call()判断

Object.prototype.toString.call(NaN) // "[object Number]"
Object.prototype.toString.call([1,2]) // "[object Array]"
// 函数表达式
Object.prototype.toString.call(()=>console.log(1)) // "[object Function]"
// 函数声明
Object.prototype.toString.call(window.testF) // "[object Function]"
Object.prototype.toString.call("str") // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(null) // "[object Null]"

数组特殊判断

这个接口是ES5之后才有的,游戏开发的话,应该没问题,使用的一般是ES5和ES6规范

Array.isArray([]) // true

NaN特殊判断

isNaN(number)

测试

function testFunc() {
    console.log("testFunc");
}
let testArr = {
    "NaN": NaN,
    "null": null,
    "undefined": undefined,
    "1": 1,
    "[1,2]": [1, 2],
    "testFunc": testFunc,
    "testFunc2": () => console.log("testFunc2"),
    "obj": {
        "a": 1
    },
    "boolean": true,
    "string": "strxxxx"
};
for (let k in testArr) {
    try {
        console.log("typeof ==>", k, typeof testArr[k]);
        console.log("instanceof Object ==>", k, testArr[k] instanceof Object);
        console.log("Object.prototype.toString.call() ==>", k, Object.prototype.toString.call(testArr[k]));
        console.log("constructor ==>", k, testArr[k].__proto__.constructor);
    }
    catch(e){
        console.log(e);
    }
    console.log("");
}
// 下面是输出结果
typeof ==> 1 number
instanceof Object ==> 1 false
Object.prototype.toString.call() ==> 1 [object Number]
constructor ==> 1 function Number() { [native code] }

typeof ==> NaN number
instanceof Object ==> NaN false
Object.prototype.toString.call() ==> NaN [object Number]
constructor ==> NaN function Number() { [native code] }

typeof ==> null object
instanceof Object ==> null false
Object.prototype.toString.call() ==> null [object Null]
TypeError: Cannot read property '__proto__' of null
    at Object.<anonymous> (/Users/tu/self/learn/learn-js/test-types/main.js:23:54)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3

typeof ==> undefined undefined
instanceof Object ==> undefined false
Object.prototype.toString.call() ==> undefined [object Undefined]
TypeError: Cannot read property '__proto__' of undefined
    at Object.<anonymous> (/Users/tu/self/learn/learn-js/test-types/main.js:23:54)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3

typeof ==> [1,2] object
instanceof Object ==> [1,2] true
Object.prototype.toString.call() ==> [1,2] [object Array]
constructor ==> [1,2] function Array() { [native code] }

typeof ==> testFunc function
instanceof Object ==> testFunc true
Object.prototype.toString.call() ==> testFunc [object Function]
constructor ==> testFunc function Function() { [native code] }

typeof ==> testFunc2 function
instanceof Object ==> testFunc2 true
Object.prototype.toString.call() ==> testFunc2 [object Function]
constructor ==> testFunc2 function Function() { [native code] }

typeof ==> obj object
instanceof Object ==> obj true
Object.prototype.toString.call() ==> obj [object Object]
constructor ==> obj function Object() { [native code] }

typeof ==> boolean boolean
instanceof Object ==> boolean false
Object.prototype.toString.call() ==> boolean [object Boolean]
constructor ==> boolean function Boolean() { [native code] }

typeof ==> string string
instanceof Object ==> string false
Object.prototype.toString.call() ==> string [object String]
constructor ==> string function String() { [native code] }

结论

js中最好的类型判断方法应该是使用Object.prototype.toString.call()来判断,因为 这种方法能判断大部分类型,唯一不能区分的是NaNNumber,因为NaN也是Number. 我们可以跟isNaN(number)组合使用。

results matching ""

    No results matching ""