六种基本数据类型和三种引用数据类型:
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
数据存储方式
原始数据类型也称基础数据类型,是不可拆分的数据类型,他存在于栈中;而引用数据类型也是通常意义上所说的类,存在于堆中。
这两者的一个重要的区别在于原始数据类型在赋值的时候使用的是传值的方式,而引用数据类型在赋值时使用的是传址(指针)的方式
数据类型判断
1、typeof()函数
对于原始数据类型,我们可以使用typeof()函数来判断他的数据类型:
typeof(1) //number typeof("1") //string typeof(true) //boolean typeof(undefined) //undefined typeof(null) //object
注释:您也许会问,为什么 typeof 运算符对于 null 值会返回 "object"。这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值。
typeof能准确判断 :5中基本数据类i型boolean、number、string、undefined和一种引用数据类型function(引用类型除了function其他都是Object)。
typeof不能区分Null、Array、Date、 RegExp 、Object
2、instanceof
typeof()函数对于原始类型的判断还差强人意,但他是没法用来区分引用数据类型的,因为所有的引用数据类型都会返回"object"。于是javascript引入了java中使用的instanceof,用来判断一个变量是否是某个对象的实例,所以对于引用类型我们使用instanceof来进行类型判断。
var obj = {}; obj instanceof Object; //true var arr = []; arr instanceof Array; //true var now = new Date(); now instanceof Date; //true var func = function(){}; func instanceof Function; //true var str = "string"; str instanceof String; //false
如上面所示,instanceof对于引用类型的支持很好,但他是无法对原始类型进行判断,所以一般都是在typeof判断为object时才使用instanceof。(PS:还是不能判断null类型; 数组 instanceof Object 也是正确的!)
3、Object.prototype.toString.call()
在javascript高级程序设计中提供了另一种方法,可以通用的来判断原始数据类型和引用数据类型,先看代码:
参照博客:https://www.cnblogs.com/a546558309/p/3608194.html
var num1 = 1; var num2 = new Number(1); Object.prototype.toString.call(num1) == "[object Number]"; //true Object.prototype.toString.call(num2) == "[object Number]"; //true var arr = []; Object.prototype.toString.call(arr) == "[object Array]"; //true var func = function(){}; Object.prototype.toString.call(func) == "[object Function]"; //true function A(){}; var a = new A(); Object.prototype.toString.call(a) == "[object Object]"; //true
如上所示,这个方法提供了一个通用的数据类型判断模式,虽然对于自定义类的判断还没法做到,但在日常的类型判断中我们更多的是针对非自定义类,对于自定义类我们也可以转使用instanceof来进行判断,所以这种方法可以成为一种通用的类型判断方法。
下面附上常用的类型判断函数集合:
var valide = (function(){ // 是否是字符串 function isString(value){ return Object.prototype.toString.call(value) == "[object String]"; } // 是否是数字 function isNumber(value){ return Object.prototype.toString.call(value) == "[object Number]"; } // 是否是布尔值 function isBoolean(value){ return Object.prototype.toString.call(value) == "[object Boolean]"; } // 是否undefined function isUndefined(value){ return Object.prototype.toString.call(value) == "[object Undefined]"; } // 是否是null function isNull(value){ return Object.prototype.toString.call(value) == "[object Null]"; } // 是否数组 function isArray(value){ return Object.prototype.toString.call(value) == "[object Array]"; } // 是否是函数 function isFunction(value){ return Object.prototype.toString.call(value) == "[object Function]"; } // 是否是对象 function isObject(value){ return Object.prototype.toString.call(value) == "[object Object]"; } // 是否是正则表达式 function isRegExp(value){ return Object.prototype.toString.call(value) == "[object RegExp]"; } // 是否是日期对象 function isDate(value){ return Object.prototype.toString.call(value) == "[object Date]"; } return { isString: isString, isNumber: isNumber, isBoolean: isBoolean, isUndefined: isUndefined, isNull: isNull, isArray: isArray, isFunction: isFunction, isObject: isObject, isRegExp: isRegExp, isDate: isDate }; })();
更简单的写法:
var Type = ( function () { var type = {}; var typeArr = [ 'String' , 'Object' , 'Number' , 'Array' , 'Undefined' , 'Function' , 'Null' , 'Symbol' ]; for ( var i = 0; i < typeArr.length; i++) { ( function (name) { type[ 'Is' + name] = function (obj) { return Object.prototype.toString.call(obj) == '[object ' + name + ']' ; } })(typeArr[i]); } return type; })(); |
调用方法:Type.IsFunction( function () {}) Type.IsObject({})。。。。。 |
Type.Is..... |
4、constructor
在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用
就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的
如: (a instanceof Array) //a是否Array的实例?true or false
(a.constructor == Array) // a实例所对应的构造函数是否为Array? true or false
举个例子:
function employee(name,job,born){ this.name=name; this.job=job; this.born=born; } var bill=new employee("Bill Gates","Engineer",1985); console.log(bill.constructor); //输出function employee(name, jobtitle, born){this.name = name; this.jobtitle = job; this.born = born;}
那么判断各种类型的方法就是:
console.log([].constructor == Array); console.log({}.constructor == Object); console.log("string".constructor == String); console.log((123).constructor == Number); console.log(true.constructor == Boolean);
较为严谨并且通用的方法:
function isArray(object){ return object && typeof object==='object' && Array == object.constructor; }
!!注意:
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!
/*********************************************************/
另外可参照博客:https://www.cnblogs.com/dushao/p/5999563.html#4028666
补充jquery判断js数据类型
$.isArray([1,2]); // 数组 $.isFunction(function () { }); // 函数function $.isEmptyObject(null); // null,undefind $.isXMLDoc(); // xml typeof (2) === "number"; // 数字 typeof ("2") === "string"; // 字符串 typeof (true) === "boolean";// bool型 typeof (function () { }) === "function";// 函数function
var Type = ( function () { var type = {}; var typeArr = [ 'String' , 'Object' , 'Number' , 'Array' , 'Undefined' , 'Function' , 'Null' , 'Symbol' ]; for ( var i = 0; i < typeArr.length; i++) { ( function (name) { type[ 'Is' + name] = function (obj) { return Object.prototype.toString.call(obj) == '[object ' + name + ']' ; } })(typeArr[i]); } return type; })(); |
调用方法:Type.IsFunction( function () {}) Type.IsObject({})。。。。。 |
Type.Is..... |