JavaScript 中判断值类型的三种方法

JavaScript有三种方法,可以确定一个值到底是什么类型。

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString方法

首先,来了解一下js中的数据类型种类。

数据类型

JavaScript的数据类型,共有六个类别和两个特殊值。

六个类别的数据类型又可以分成两组:原始类型(primitive type)和合成类型(complex type)。

原始类型包括三种数据类型。

  • 数值(number
  • 字符串(string
  • 布尔值(boolean

合成类型也包括三种数据类型。

  • 对象(object
  • 数组(array
  • 函数(function

另外两个特殊值分别是 nullundefined

typeof运算符

typeof 运算符可以返回一个值的数据类型,可能有以下结果。

1)原始类型

数值、字符串、布尔值分别返回 numberstringboolean

2)函数

函数返回 function

3)undefined

undefined 返回 undefined

4)其他

除此以外,包括 []{}nullwindow ,都返回 object

1
2
3
4
5
6
7
8
9
10
typeof 123 // "number"
typeof "123" // "string"
typeof false // "boolean"
typeof f(){} // "function"
typeof undefined // "undefined"

typeof window // "object"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"

很显然,typeof 无法对数组(array)和对象(object)进行区分。

instanceof运算符

instanceof 运算符可以解决 typeof 无法区分数组和对象的问题。

instanceof 运算符用来确定一个对象是否为某个构造函数的实例,运算符的左边放置对象,右边放置构造函数。

1
2
[1, 2, 3] instanceof Array // true
({}) instanceof Object // true

但是,由于原始类型的值不是对象,所以不能使用 instanceof 运算符判断类型。

1
2
"" instanceof String // false
1 instanceof Number // false

instanceof操作符问题在于,它假定只有一个全局执行环境,如果网页中有多个框架,那实际上就存在两个不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果我从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有不同的构造函数。

以上引自 wangyingwy

即,在跨frame对象构建时,instanceof 操作符对 Array 的判断会失灵,参考 js如何判断一个对象是不是Array

Object.prototype.toString方法

toString方法的作用是返回一个对象的字符串形式。

字符串 [object Object] 本身没有太大的用处,但是通过自定义 toString 方法,可以让对象在自动类型转换时,得到想要的字符串形式。

数组、字符串和函数都分别部署了自己版本的 toString 方法。toString 方法的另一个重要作用,就是判断一个值的类型。

不同数据类型的 toString 方法返回值如下:

  • 数值:返回[object Number]。
  • 字符串:返回[object String]。
  • 布尔值:返回[object Boolean]。
  • undefined:返回[object Undefined]。
  • null:返回[object Null]。
  • 对象:返回”[object “ + 构造函数的名称 + “]” 。

利用这个特性,写出一个比 typeof 运算符更准确的类型判断函数。

1
2
3
4
5
6
7
8
9
10
11
12
var type = function (o){
var s = Object.prototype.toString.call(o);
return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"

参考

JavaScript标准参考教程(阮一峰):

typeof运算符
instanceof运算符
Object.prototype.toString()

坚持原创技术分享,您的支持将鼓励我继续创作!