By
特首
更新日期:
前言
理解Javascript的类型是学习Javascript的基础,但是作为新手很容易在判断Javascript上容易混淆,所以在此整理清自己的思路。
类型
JavaScript 中所有变量都是对象,除了两个例外 null 和 undefined。
作为新手很容易被上面这句话误导,首先解释下上面这句话。
1 2 3
| false.toString(); [1, 2, 3].toString(); (2).toString();
|
通过上面的代码,可以看出布尔、数组、数字都具有toString()
这一方法,其实除了null
和undefined
外的数据类型都继承自Object
对象都具Object
的方法和属性,这些看似非对象的类型使用起来却很像对象,所以也可以说它们都是对象。可是Javascript依然具有类型,我想大致可以分成下面几类:
- Number
- String
- Boolean
- Object
- Null
- Undefined
Number
、String
、Boolean
、Null
、Undefined
都是是基本数据类型,只有Object
属于复杂数据类型。Null
和Undefined
都表示空,它们的区别在于:Null
表示无值,一般是人为的将变量的值设置为null
;Undefined
表示未知值,一般在使用var声明变量但未对其加以初始化时,这个变量值为undefined
。
Object
又分为以下几种类型:
- Object
- Function
- Array
- Date
- RegExp
typeof操作符
typeof
操作符(和instanceof
一起)或许是 JavaScript 中最大的设计缺陷, 因为几乎不可能从它们那里得到想要的结果。
1 2 3 4 5 6 7 8 9 10
| typeof []; typeof {}; typeof ''; typeof new Date() typeof 1; typeof function () {}; typeof /test/i; typeof true; typeof null; typeof undefined;
|
为什么?function
明明是Object
类型,却显示function
;null
明明是Null
类型,却显示’object’。所以typeof
操作符对类型的判断是不靠谱的,除非类型在给定的范围且typeof
确实能够区分这些类型。
类型的区分
Javascript标准标准文档给出了区分类型的办法:
1
| Object.prototype.toString.call();
|
我们来看看上面的方法效果如何:
1 2 3 4 5 6 7 8 9 10
| Object.prototype.toString.call([]); Object.prototype.toString.call({}); Object.prototype.toString.call(''); Object.prototype.toString.call(new Date()); Object.prototype.toString.call(1); Object.prototype.toString.call(function () {}); Object.prototype.toString.call(/test/i); Object.prototype.toString.call(true); Object.prototype.toString.call(null); Object.prototype.toString.call();
|
效果确实比typeof
操作符号不一样,那我们在判断的时候就可以这么使用了:
1 2 3 4 5 6 7 8 9 10
| var getType = function (elem) { return Object.prototype.toString.call(elem); }, person = {}; person.getName = function () { return 'Jason'; }; if (getType(person) === '[object Object]') { person.getName(); }
|
可是这样还不够完美,因为Object.prototype.toString.call()
返回值是字符串所以可以用.slice(8, -1)
方法去掉[object
和]
。所以我们再改进一下:
1 2 3 4 5 6 7 8 9 10
| var getType = function (elem) { return Object.prototype.toString.call(elem).slice(8, -1); }, person = {}; person.getName = function () { return 'Jason'; }; if (getType(person) === 'Object') { person.getName(); }
|
写个类库
利用上面判断类型的方法可以写个类库,此类库来自(Axis.js)[//github.com/toddmotto/axis]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| (function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory); } else if (typeof exports === 'object') { module.exports = factory; } else { root.axis = factory(); } })(this, function () { 'use strict'; var exports = {}; var types = 'Array Object String Date RegExp Function Boolean Number Null Undefined'.split(' '); var type = function () { return Object.prototype.toString.call(this).slice(8, -1); }; for (var i = types.length; i--;) { exports['is' + types[i]] = (function (self) { return function (elem) { return type.call(elem) === self; }; })(types[i]); } return exports; });
|
使用方法也很简单:
1 2 3 4 5 6 7 8 9 10
| axis.isArray([]); axis.isObject({}); axis.isString(''); axis.isDate(new Date()); axis.isRegExp(/test/i); axis.isFunction(function () {}); axis.isBoolean(true); axis.isNumber(1); axis.isNull(null); axis.isUndefined();
|
参考链接: