细说javascript typeof操作符
2015-08-21 16:55
525 查看
细说javascript typeof操作符
typeof定义
typeof是一元运算符,用来返回操作数类型的字符串。下面是ECAMScript5.1关于typeof的标准定义:NOTE:上面表格标红处应为“object”。
typeof疑惑
Value Class Type ------------------------------------- null null object "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object new RegExp("meow") RegExp object {} Object object new Object() Object object
NOTE:上面表格中,Class 一列表示对象的内部属性
[[Class]]的值,Type 一列表示
typeof操作符的运算结果。
仔细观察上面的javascript类型表格,聪明的你也许已经发现了问题所在:type列大多数情况下都返回 "object"并且和class列的值不一致。因此可以说typeof运算符可以用来获取操作数类型,但很可能得不到想要的结果,所以不应该用typeof来检测对象的类型。说的这里你可能会有疑惑了,typeof不能用来检测对象类型那用来干嘛,到底该怎么检测对象的类型?
别着急,先来看看对象的[[Class]]这个内部属性:
对于object的内部属性[[Class]],ECMAScript5.1是这么说的:ECAMScript规范每种内置对象都定义了 [[Class]] 内部属性。宿主对象的 [[Class]] 内部属性的值可以是"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String" 的任何字符串。[[Class]] 内部属性的值用于内部区分对象的种类。
NOTE:规范中除了通过 Object.prototype.toString ( ) 没有提供任何手段使程序访问此值。
明白了,原来可以通过 Object.prototype 上的toString()方法获取[[Class]]属性,[[Class]]属性就是对象的真正类型,那我们就来看看Object.prototype.toString ( ) 是何方圣神:
是不是有点豁然开朗的感觉,于是很快写出以下代码:
/** * _typeof() returns type of obj * * @obj 要检测的对象 */ function _typeof(obj) { // Object.prototype.toString 返回一种标准格式字符串("[object ", class, and "]"), // 所以通过 slice 截取指定位置的字符串 return Object.prototype.toString.call(obj).slice(8, -1); } //测试结果 >_typrof([]) ‘Array’ >_typrof(null) ‘null’ >typrof new abc/g ‘RegExp’
到这里大家也许会想不过如此,如果你真的这么认为,只能对你说句Too young Too simple,请往下看:
// IE678 Object.prototype.toString.call(null) // "[object Object]" Object.prototype.toString.call(undefined) // "[object Object]"
那么到底如何正确的判断javascript的数据类型又做到浏览器的兼容呢,聪明的你应该已经想到了jquery,来看看jQuery.type()是怎样实现的:
var class2type = {}; "Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function (e, i) { class2type["[object " + e + "]"] = e.toLowerCase(); }); //当然为了兼容IE低版本,forEach需要一个polyfill,不作细谈了。 function _typeof(obj) { if (obj == null) { return String(obj); } return typeof obj === "object" || typeof obj === "function" ? class2type[class2type.toString.call(obj)] || "object" : typeof obj; } // IE678 >_typrof(null) ‘null’ >_typrof(undefined) ‘undefined
关于数据类型的判断到这里就告一段落了,既然typeof不能用作数据类型的判断,那typeof可以应用在哪方面呢,往下看。
typeof用途
1.检测变量是否定义或是否赋值Typeof会在两种情况下返回‘undefined’::一个变量没有被声明的时候,和一个变量的值是undefined的时候。
> typeof undeclaredVariable
'undefined'
> var declaredVariable;
> typeof declaredVariable
'undefined'
2.区分对象值和原始值
function isObject(obj) { var type = typeof obj; //typeof把函数和对象看成是不同的类型,而且typeof null返回"object" return (type === 'function' || (type === 'object' && !!Obj)); }
3.某个值是否是函数
function isFunction(obj) { //这样做是会出现兼容性的问题(IE 11, Safari 8),有兴趣的朋友可以去了解 return typeof obj === 'function'; }
总结
通过本文我们了解到,检测一个对象的类型尽量使用Object.prototype.toString()方法,以及如何做到个浏览器的兼容性。关于typeof操作符,虽然列举了几个典型的应用场景,不过建议除非为了检测一个变量是否已经定义,尽量避免使用typeof操作符。参考
http://es5.github.io/http://lzw.me/pages/ecmascript/
http://bonsaiden.github.io/JavaScript-Garden/zh/
相关文章推荐
- js this
- jsduck命令帮助
- 转:执行ajax加载页面中的js
- Javascript 执行环境及作用域
- 获取Json文件的方法
- js+正则+单双引号问题
- js实现类似trim函数
- javascript 的点击复制事件
- jsDuck的注释说明
- Javascript仿新浪游戏频道鼠标悬停显示子菜单效果
- JavaScript 常见安全漏洞和自动化检测技术
- js+css实现文字散开重组动画特效代码分享
- js个人笔记
- Winform中调用js函数
- json-server模拟服务器数据
- js到服务器端的URL中文乱码问题
- JSON 解析器。JSON.stringify和JSON.parse
- "Could not load file or assembly \u0027Newtonsoft.Json, Version=4.5.0.0
- JS给元素增加className
- 21、javascript 基础