这篇文章主要介绍了如何判断 JavaScript 中对象的类型, 举例讲解了使用 typeof 和 instanceof 等操作符来进行判断的方法, 需要的朋友可以参考下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
在编写 js 程序的过程中,可能常常需要判断一个对象的类型,例如你写了一个函数,需要通过判断不同的参数类型来编写不同的代码。
首先可能会想到 typeof 操作符,看下面的这个例子:
- <script type="text/javascript">
- var object = {};
- var b = true;
- alert(typeof object + " " + typeof b);
- </script>
得到的结果如下:
从上面的结果可以看到,用 typeof 操作符可以显示对象的类型,那么 typeof 操作符作用域 null 和 undefined 的结果会是什么呢?
- /*var object = {};
- var b = true;
- alert(typeof object + " " + typeof b);*/
- alert(typeof null + " " + typeof undefined)
typeof 操作符作用于 null 居然显示 "object"(这个好像不科学,我还以为会显示 "null'"),作用于 undefined 显示 "undefined"(这个符合我们希望的结果),所以当用 typeof 操作符来判断一个对象的类型时,特别要小心,因为这个对象有可能是 null。上面只是给了一部分 typeof 作用于这些对象的结果,下面的表列出了 typeof 操作符作用于 Boolean, Number, String, Array, Date, RegExp, Object, Function, null, undefined 的结果(有兴趣的读者可以自行测试):
从上表的结果可以看出 Array, Date, RegExp 显示的都是 object,为什么不是直接的显示对象的类型呢?这就要引出 js 的另外一个操作符了: instanceof 操作符,这个操作符用来判断一个对象是否为某种类型的对象,计算的值为 true 或者 false。先来看下:
- var now = new Date();
- var pattern = /^[\s\S]*$/;
- var names = ['zq', 'john'];
- alert((now instanceof Date) + " "
- + (pattern instanceof RegExp) + " " + (names instanceof Array));
很显然通过这个 instanceof 是能判断对象的类型的,但是这个只能判断除了基本类型(包含 String 类型)的其它类型,他是不能判断基本类型的。但是 instanceof 不是总是能正常判断的,考虑一个框架的情形,要判断其类型的对象是另外一个 frame 传递过来的对象,首先来看下下面的例子。
main.html
- <!doctype html>
- <html lang="en">
- <head>
- <title>
- Main
- </title>
- </head>
- <frameset cols="45%,*">
- <frame name="frame1" src="frame1.html" />
- <frame name="frame2" src="frame2.html" />
- </frameset>
- </html>
frame1.html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- frame1
- </title>
- </head>
- <script type="text/javascript">
- var names = ['riccio zhang', 'zq', 'john'];
- </script>
- <body style="background: #ccc">
- </body>
- </html>
frame2.html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- frame2
- </title>
- <script type="text/javascript">
- document.write("top.frame1.names instanceof Array:" + (top.frame1.names instanceof Array));
- document.write("<br/>");
- document.write("top.frame1.names instanceof top.frame1.Array:" + (top.frame1.names instanceof top.frame1.Array));
- document.write("<br/>");
- document.write("top.frame1.Array === top.frame2.Array?" + (top.frame1.Array === top.frame2.Array));
- </script>
- </head>
- <body style="background: #747474">
- </body>
- </html>
names 对象是在 frame1 框架中的,此时是通过 frame1 框架的 Array 来创建的,如果把 names 对象拿到 frame2 中的 Array 作比较,很显然 names 不是 frame2 中的 Array 的实例,以为 frame1 和 frame2 压根就不是同一和 Array,从第 2 个现实结果可以很明显的看出 names 是他本身所在的 frame 的实例,从第 3 个输出可以看出 frame1 的 Array 和 frame2 的 Array 是不同的。那么遇到上面这种跨 frame 的比较该怎么办呢?我们总不能每次都拿框架对应的 Array 来做比较吧,有一种必须的办法可以解决上面的问题,看下面的代码:
- var toString = {}.toString;
- var now = new Date();
- alert(toString.call(now))
{}.toString 表示获取 Object 对象上的 toString 方法(这个方法时 Object 对象的基本方法之一),toString.call(now)表示调用 toString 方法。调用 Date 对象最原生的 toString()(这个方法是 Object 上面的方法)方法可以显示 [object Date] 类型的字符串,假如是 Array,则会产生 [object Array] 的字样,也就是说进行上面的操作会显示类似 [object Class] 的字样,那么我们只要判断这个字符串不就可以知道其类型了吗?由此可以写出如下的工具类:
tools.js
- var tools = (function(undefined){
- var class2type = {},
- toString = {}.toString;
- var fun = {
- type: function (obj){
- return obj === null || obj === undefined ?
- String(obj) : class2type[toString.call(obj)]
- },
- isArray: function (obj){
- return fun.type(obj) === "array";
- },
- isFunction: function (obj){
- return fun.type(obj) === "function";
- },
- each: function (arr, callback){
- var i = 0,
- hasLength = arr.length ? true : false;
- if(!callback || (typeof callback !== 'function') || !hasLength){
- return;
- }
- for(i = 0; i< arr.length; i++){
- if(callback.call(arr[i], i, arr[i]) === false){
- break;
- }
- }
- }
- };
- fun.each("Boolean Number String Array Date RegExp Object Function".split(" "), function(i, name){
- class2type["[object "+ name +"]"] = name.toLowerCase();
- });
- return fun;
- })();
tools 提供了 type,isArray,isFunction 等方法用来判断对象的类型,根据实际的需要可以自己添加需要判断类型的方法。type 接受一个 obj 参数,它将对象的实际类型以小写的形式返回,比如你的需要判断对象的类型是 Array,那么此方法将会返回 array.
根据上面提供的工具类,再重新改写上面的例子:
fram2.html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- frame2
- </title>
- <script type="text/javascript" src="tools.js">
- </script>
- <script type="text/javascript">
- document.write("top.frame1.names instanceof Array:" + (top.frame1.names instanceof Array));
- document.write("<br/>");
- document.write("top.frame1.names instanceof top.frame1.Array:" + (top.frame1.names instanceof top.frame1.Array));
- document.write("<br/>");
- document.write("top.frame1.Array === top.frame2.Array?" + (top.frame1.Array === top.frame2.Array));
- document.write("<br/>");
- document.write("tools.isArray(top.frame1.names)?" + tools.isArray(top.frame1.names));
- </script>
- </head>
- <body style="background: #747474">
- </body>
- </html>
至此通过上面的根据类就可以很容易的判断对象的类型了。
注意:在 IE 中例如像 alert 这样的元素是不能判断的。
来源: http://www.phperz.com/article/17/0401/266203.html