前言
ECMAScript中有5种数据类型,分别为Number,Boolean,Null,Undifined和String,以及一种复杂的数据类型Object(由名值对组成,是这门语言所有对象的基础类型).后来 ES6又添加了一种新的数据类型 Symbol(只存在于ES6).
复杂的数据类型Object 类型,即引用类型,细分的话,有:Object 类型
、Array 类型
、Date 类型
、RegExp 类型
、Function 类型
等。后 ES6又添加了 Set 和 Iterator 两种新的数据类型。 ES6 更多新的知识 可以看看 阮一峰 老师的博文 《ESCMScript6入门》;
ECMAScript是松散类型,是弱类型语言。
基础
先看看值类型和引用类型的区别;
var a=10; var b=a;
a++;
基本类型是不可变的,基本类型在赋值操作后,两个变量是相互不受影响的
var a={ value: 10; }; var b=a; a.vaule++;
引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
类型检测
在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加。之所以不同的数据类型之间可以做运算,是因为JavaScript引擎在运算之前会悄悄的把他们进行了隐式类型转换的,如下是数值类型和布尔类型的相加:
因此,有时候会发生 类型错误有可能会被类型转换所隐藏 等情况,所以我们要进行类型检测。
1.typeof 操作符 :经常用来检测一个变量是不是最基本的数据类型
var str='abc'; typeof(str); // 'string' typeof str; // 'string' typeof 92; // 'number' typeof true; // 'boolean' typeof a; // "undefined" 未声明的变量 a 或者 声明后未初始化的变量 a typeof null;// 'object'
注意点:
① 特殊值 null 会被当成空的对象引用,因此会返回 'object'
② undefined 派生自 null ,所以 进行弱相等特性检测时会返回 true
null==undefined ; // true null===undefined; // false
-
= =
: 只进行值的比较 -
= = =
: 不仅进行值得比较,还要进行数据类型的比较
所以,上面 null==undefined 时,进行了数据类型的隐式类型转换,结果返回 true 。
typeof /w/ ; // "object"
③ Safari 5 及之前和 chrome 7 及其之前,对于typeof 正则表达式 会返回‘function’,其他返回 ‘object’
2. instanceof 操作符 :用来判断某个构造函数的 prototype 属性所指向的对象是否存在于另外一个要检测对象的原型链上
({}) instanceof Object // true ([]) instanceof Array // true (/aa/g) instanceof RegExp // true (function(){}) instanceof Function // true
再看下面这个例子
1 function SuperType(){ 2 } 3 function SubType(){ 4 } 5 6 SubType.prototype=new SuperType(); 7 8 var instance= new SubType(); 9 instance instanceof SuperType; // true 10 instance instanceof SubType; // true
通过 SubType构造函数创建了 instance 实例,因此
instance.__proto__ == SubType.prototype
又由于
SubType.prototype=new SuperType();
因此, instance instanceof SuperType; // true
3. 安全的类型检测
在任何值上调用 Object的原生方法 toString(),会返回一个 [object NativeConstructorName]的字符串,根据这一点我们可以检测原生javascript对象,注意开发人员自定义的任何构造函数都会返回 [object Object];
Object.prototype.toString.call(value);
基于这一思路我们可以创建
function isArray(value){ if(typeof Array.isArray=='function'){ return Array.isArray(value); } return Object.prototype.toString.call(value)=="[object Array]"; }
检测原生函数和正则表达式:
function isFunction(value){ return Object.prototype.toString.call(value)=="[object Function]"; } function isRegExp(value){ return Object.prototype.toString.call(value)=="[object RegExp]"; }
结束语
以上总结了js类型检测的基本方法,以及简单的介绍了基础类型和引用类型。javascript本就是弱类型语言,如果真的很纠结数据类型的话,不妨可以去看看 TypeScript .