JavaScript数据类型检测

 2015年03月06日    84     声明


1. JavaScript中的数据类型

JavaScript的数据类型分为两类:原始类型(Primitive type)、引用类型(Reference type),二者在内存中的存储位置不同。判断一个变量属于哪种类型,这两类数据类型的判断方式也有所有不同,分别使用typeofinstanceof进行检测。

原始类型

原始类型就叫做基本类型,在ECMAScript 5标准中共规定了5种基本类型,分别是:数字类型(Number字符串类型(String、布尔值(Boolean)、NullUndefined。在ECMAScript 2015(ECMAScript 5)中,还新增了Symbol

原始类型存储在内存栈(stack)中,也就是说直接存储的变量的值。对于原始类型的访问是值访问,我们可以直接操作变量的实际值。

引用类型

除了6种原始类型外,都是引用类型。主要有:对象类型(Object数组类型(Array日期类型(Date、错误类型(Error)、正则表达式类型(RegEx、函数类型(Function)等。在ECMAScript 2015中,还新增了PromiseMap等引用类型。

引用类型是存储在内存堆(heap)中对象,也就是说直接存储的变量的值是一个指向原对象内存指针。对于原始类型的访问是引用访问,我们不能直接操作对象的实际内存空间。


2. 原始类型的检测

检测原始类型时,除Null类型外,都可以使用typeof操作符检测。typeof检测后会返回一个表示检测对象类型的字符串。typeof语法如下:

typeof <变量>

或者:

typeof(<变量>)

使用typeof进行原始类型检测时,其返回值分别如下:

  • Number类型返回'number'
  • String类型返回'string'
  • Boolean类型返回'boolean'
  • Undefined类型返回'undefined'
  • Null类型返回'object'
  • Symbol类型返回'symbol'

示例如下:

var str = 'http://itbilu.com';
typeof str;     // 'string'
var num = 0;
typeof num;     // 'number'
typeof true;    // 'boolean'
var undefin;
typeof undefin; // 'undefined'
typeof null;    // 'object'
typeof Symbol('itbilu.com'); // 'symbol'

对于原始类型中Null类型进行typeof检测时返回值为'object',要正确判断是否是Null类型,应该使用===!==进行比较。


3. 引用类型的检测

除原始类型外都是引用类型,而JavaScript中Object类型是所有引用类型的基类型,所以大多数引用类型使用typeof检测时都会返回'object'

示例如下:

typeof [];           // 'object'
typeof new Date();   // 'object'
typeof {};           // 'object'
typeof new Error();  // 'object'
typeof new RegExp(); // 'object'
typeof Function;     // 'function'

如上所示,除Function,其它引用类型都返回了'object'typeof运算符并不能有效检测引用类型。

对于引用类型来说,更推荐使用instanceof运算符检测。其语法结构为:

value instanceof constructor

对上面引用类型做instanceof检测结果如下:

[] instanceof Array;         // true
new Date() instanceof Date;  // true
{} instanceof Object;        // true
new Error() instanceof Error;// true
var reg = new RegExp();
reg instanceof RegExp;       // true
function func () {}
func instanceof Function;    // true


附:对象属性检测

检测对象属性时,可以使用in运算符,或使用对象的实例方法hasOwnProperty()。前者用于检测对象属性是否继承自原型链,而后者只会检测属性是否存在。

示例如下:

function Person() {
  this.name = 'liuht';
  this.doSometing = function() {
    return 'doSometing';
  }
}
Person.prototype.area = 'China';  // 原型链属性

var man = new Person();
man.sex = 'man';

console.log('name' in man);  // true
console.log('sex' in man);   //	true
console.log('area' in man);  // true

man.hasOwnProperty('name');  // true
man.hasOwnProperty('sex');   // true
man.hasOwnProperty('area');  // false