# javascript中如何判断变量类型?
# typeof
判断基本类型,返回一个字符串
typeof 123 === 'number' // true
类型 | 结果 |
---|---|
Undefined | "undefined" |
Null | "object"(见下文) |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol (ECMAScript 6 新增) | "symbol" |
宿主对象(由JS环境提供) | Implementation-dependent |
函数对象([[Call]] 在ECMA-262条款中实现了) | "function" |
任何其他对象 | "object" |
# instanceof
检查某个对象属于哪个构造函数
function A(){}
let a = new A()
a instanceof A // true
# 更详细的解释
由于具体实现上的问题,在实际的项目应用中,typeof只有两个用途,就是检测一个元素是否为undefined,或者是否为function。
# 为何呢?
JavaScript Garden整理出来了如下表格:
Value | function | typeof |
---|---|---|
"foo" | String | string |
new String("foo") | String | object |
1.2 | Number | number |
new Number(1.2) | Number | object |
true | Boolean | boolean |
new Boolean(true) | Boolean | object |
new Date() | Date | object |
new Error() | Error | object |
[1,2,3] | Array | object |
new Array(1, 2, 3) | Array | object |
new Function("") | Function | function |
/abc/g | RegExp | object |
new RegExp("meow") | RegExp | object |
{} | Object | object |
new Object() | Object | object |
所以我们一般用“鸭子类型”来做流程控制。
# 一定要区分这些东西?
Object.prototype.toString()
有一个妙用,如果我们以某个特别的对象为上下文来调用该函数,它会返回正确的类型。我们需要做的就是手动处理其返回的字符串,最终便能获得typeof应该返回的正确字符串。
可以用来区分:Boolean, Number, String, Function, Array, Date, RegExp, Object, Error
等等。
jQuery.type()就是这样实现的。以下代码从jQuery源码中抽取出来,可以直接用。
var class2type = {} ;
"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(e,i){
class2type[ "[object " + e + "]" ] = e.toLowerCase();
}) ;
//当然为了兼容IE低版本,forEach需要一个polyfill,不作细谈了。
function _typeof(obj){
if ( obj == null ){
return String( obj );
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ class2type.toString.call(obj) ] || "object" :
typeof obj;
}
使用结果:
_typeof(new String())
->"string"
_typeof("123")
->"string"
_typeof(new RegExp())
->"regexp"
_typeof(null)
->"null"
# 公认的方法
即使都是object类型,也还是有区分的。比如[object Object] [object String]...
Object.prototype.toString.call(x) === '[object Array]'
# 鸭子类型
- js是一门动态语言,指的是在运行过程中可以改变其结构等。
比如
var a=0 a='3'+5
- 鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定。
- 当看到一只鸟走起来像鸭子,游泳像鸭子,叫起来像鸭子,那么这只鸟就可以被称之为鸭子。
- 在鸭子类型中,关注点在于对象的行为,能做什么,而不是关注类型。
- 可以理解为,在不继承的情况下使用了多态。
// 应聘选手鸭子
let duck = {
voice: '嘎嘎嘎'
}
// 应聘选手鸡
let chicken = {
voice: '嘎嘎嘎'
}
// 合唱团成员数组
let choir = []
// 加入合唱团
function joinChoir(animal) {
console.log(animal.voice)
if(animal.voice === '嘎嘎嘎') {
choir.push(animal)
}
}
// 鸭子加入
joinChoir(duck)
// 鸡加入
joinChoir(chicken)
// 合唱团组队完成
console.log(choir)