Javascript isArray 数组类型检测函数


Posted in Javascript onOctober 08, 2009

1、typeof操作符。对于Function、String、Number、Undefined这几种类型的对象来说,不会有什么问题,但是针对Array的对象就没什么用途了:
Js代码

alert(typeof null); // "object" 
alert(typeof []); // "object"

2、instanceof操作符。此操作符检测对象的原型链是否指向构造函数的prototype对象,恩,听起来不错,应该可以解决我们的数组检测问题:
Js代码
var arr = []; 
alert(arr instanceof Array); // true

3、对象的constructor属性。除了instanceof,我们还可以利用每个对象都具有constructor的属性来判断其类型,于是乎我们可以这样做:
Js代码
var arr = []; 
alert(arr.constructor == Array); // true

貌似后两个解决方案是无懈可击的,但真的是这样么?天有不测风云,当你在多个frame中来回穿梭的时候,令人沮丧的问题出现了:
Js代码
var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array; 
var arr = new xArray(1,2,3); // [1,2,3] 
// 哎呀! 
arr instanceof Array; // false 
// 哎呀呀! 
arr.constructor === Array; // false

由于每个iframe都有一套自己的执行环境,跨frame实例化的对象彼此是不共享原型链的,因此导致上述检测代码失效!怎么办怎么办??嗯,javascript是动态语言,或许万金油“鸭式辨型”(duck type)可以助我们一臂之力“如果它走起路来像鸭子,叫起来也像鸭子,那就当他是鸭子吧”,同理,可以检测某些数组对象特有的能力来做判断,这个法子已经有人用了,比如Prototype框架,来看看它实现的Object.isArray方法:
Js代码
isArray: function(object) { 
return object != null && typeof object == "object" && 
'splice' in object && 'join' in object; 
}

isArray:”object,你有splice、join这两个数组特有的方法吗?”
object:“嗯,没错我有!”
isArray:“好吧,那你就是个数组了,哪怕你是冒充的,?濉??
Js代码
var trickster = { splice: 1, join: 2 }; 
Object.isArray(trickster); // 假冒成功,耶

没错,这个解决方案给人的感觉有点别扭,任何一个具有'splice'和'join'属性的对象都能通过这个检测!怎么办怎么办怎么办??别着急,仔细想想,其实我们需要的是一个能取得对象实际类型,而且又能跨frame使用的方法即可。这不,细心的老外在翻阅ECMA262标准的时候发现了这个(btw,我也看了,怎么就没发现这个用途呢,?澹?
ECMA-262 写道
Object.prototype.toString( ) When the toString method is called, the following steps are taken: 
1. Get the [[Class]] property of this object. 
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”. 
3. Return Result (2)

上面的规范定义了Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于"[object Array]"的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。还是先来看看在ECMA标准中Array的描述吧:
ECMA-262 写道
new Array([ item0[, item1 [,…]]]) 
The [[Class]] property of the newly constructed object is set to “Array”.

于是乎,可以改写之前的isArray函数以利用这个特性,如下:
Js代码
function isArray(o) { 
return Object.prototype.toString.call(o) === '[object Array]'; 
}

call改变toString的this引用为待检测的对象,返回此对象的字符串表示,然后对比此字符串是否是'[object Array]',以判断其是否是Array的实例。也许你要问了,为什么不直接o.toString()?嗯,虽然Array继承自Object,也会有toString方法,但是这个方法有可能会被改写而达不到我们的要求,而Object.prototype则是老虎的屁股,很少有人敢去碰它的,所以能一定程度保证其“纯洁性”:)
与前面几个方案不同,这个方法很好的解决了跨frame对象构建的问题,经过测试,各大浏览器兼容性也很好,可以放心使用。一个好消息是,很多框架,比如jQuery、Base2等等,都计划借鉴此方法以实现某些特殊的,比如数组、正则表达式等对象的类型判定,不用我们自己写了。
Javascript 相关文章推荐
In Javascript Class, how to call the prototype method.(three method)
Jan 09 Javascript
javascript编程起步(第六课)
Jan 10 Javascript
javascript 面向对象全新理练之继承与多态
Dec 03 Javascript
jquery中输入验证中一个不错的效果
Aug 21 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
Oct 11 Javascript
jqplot通过ajax动态画折线图的方法及思路
Dec 08 Javascript
JavaScript整除运算函数ceil和floor的区别分析
Apr 14 Javascript
jQuery预加载图片常用方法
Jun 15 Javascript
ES6学习之变量的两种命名方法示例
Jul 18 Javascript
vuex + axios 做登录验证 并且保存登录状态的实例
Sep 16 Javascript
Vue引用Swiper4插件无法重写分页器样式的解决方法
Sep 27 Javascript
WebRTC记录音视频流(web技术分享)
Feb 24 Javascript
JavaScript 监听textarea中按键事件
Oct 08 #Javascript
jquery 最简单的属性菜单
Oct 08 #Javascript
Javascript 日期处理之时区问题
Oct 08 #Javascript
学习ExtJS table布局
Oct 08 #Javascript
学习ExtJS accordion布局
Oct 08 #Javascript
学习ExtJS form布局
Oct 08 #Javascript
学习ExtJS fit布局使用说明
Oct 08 #Javascript
You might like
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
php函数指定默认值方法的小例子
2013/12/04 PHP
PHP之uniqid()函数用法
2014/11/03 PHP
php使用Cookie实现和用户会话的方法
2015/01/21 PHP
Symfony2学习笔记之模板用法详解
2016/03/17 PHP
在Javascript中定义对象类别
2006/12/22 Javascript
Javascript 错误处理的几种方法
2009/06/13 Javascript
javascript 图片上一张下一张链接效果代码
2010/03/12 Javascript
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
SwfUpload在IE10上不出现上传按钮的解决方法
2013/06/25 Javascript
javascript闭包的高级使用方法实例
2013/07/04 Javascript
原生javascript实现DIV拖拽并计算重复面积
2015/01/02 Javascript
nodejs URL模块操作URL相关方法介绍
2015/03/03 NodeJs
原生JS和jQuery版实现文件上传功能
2016/04/18 Javascript
AngularJs html compiler详解及示例代码
2016/09/01 Javascript
Javascript中for循环语句的几种写法总结对比
2017/01/23 Javascript
AngularJS中使用three.js的实例详解
2017/07/21 Javascript
小程序实现选择题选择效果
2018/11/04 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
2018/11/21 Javascript
写gulp遇到的ES6问题详解
2018/12/03 Javascript
JavaScript实现汉字转换为拼音及缩写的方法示例
2019/03/28 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
vue 解决在微信内置浏览器中调用支付宝支付的情况
2020/11/09 Javascript
[46:55]Ti4 冒泡赛第二轮 LGD vs C9
2014/07/14 DOTA
Python ORM框架SQLAlchemy学习笔记之关系映射实例
2014/06/10 Python
python学习笔记:字典的使用示例详解
2014/06/13 Python
Python通用循环的构造方法实例分析
2018/12/19 Python
Python3实现的旋转矩阵图像算法示例
2019/04/03 Python
python实现图片转字符小工具
2019/04/30 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
2019/08/28 Python
Python树莓派学习笔记之UDP传输视频帧操作详解
2019/11/15 Python
世界上最大的在线汽车租赁预订平台:Rentalcars.com(支持中文)
2018/10/12 全球购物
写自荐信三大法宝
2014/01/24 职场文书
小学生差生评语
2014/12/29 职场文书
2017元旦、春节期间廉洁自律承诺书
2016/03/25 职场文书
python库sklearn常用操作
2021/08/23 Python