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 相关文章推荐
jquery中实现简单的tabs插件功能的代码
Mar 02 Javascript
jQuery关于导航条背景切换效果实现示例
Sep 04 Javascript
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
JavaScript在IE和FF下的兼容性问题
May 19 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
Jul 21 Javascript
Jquery+ajax+JAVA(servlet)实现下拉菜单异步取值
Mar 23 Javascript
vue的基本用法与常见指令
Aug 15 Javascript
详解如何使用webpack+es6开发angular1.x
Aug 16 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
Jan 18 jQuery
webpack中如何使用雪碧图的示例代码
Nov 11 Javascript
微信小程序实现watch监听
Jun 04 Javascript
如何使JavaScript休眠或等待
Apr 27 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
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
2015/12/18 PHP
php格式化时间戳
2016/12/17 PHP
利用JS自动打开页面上链接的实现代码
2011/09/25 Javascript
jquery Validation表单验证使用详解
2020/09/12 Javascript
详解javascript高级定时器
2015/12/31 Javascript
JS 中LocalStorage和SessionStorage的使用
2017/08/17 Javascript
Vue 滚动行为的具体使用方法
2017/09/13 Javascript
利用jqprint插件打印页面内容的实现方法
2018/01/09 Javascript
实战node静态文件服务器的示例代码
2018/03/08 Javascript
node前端开发模板引擎Jade的入门
2018/05/11 Javascript
vue-resourc发起异步请求的方法
2020/02/11 Javascript
微信jssdk踩坑之签名错误invalid signature
2020/05/19 Javascript
Python中urllib+urllib2+cookielib模块编写爬虫实战
2016/01/20 Python
浅谈Python中用datetime包进行对时间的一些操作
2016/06/23 Python
不管你的Python报什么错,用这个模块就能正常运行
2018/09/14 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
2019/06/27 Python
python读取并写入mat文件的方法
2019/07/12 Python
python使用自定义钉钉机器人的示例代码
2020/06/24 Python
Python定义一个Actor任务
2020/07/29 Python
Python自动创建Excel并获取内容
2020/09/16 Python
CSS3实现简易版的刮刮乐效果
2016/09/27 HTML / CSS
领先的英国注册在线药房 :Simply Meds Online
2019/03/28 全球购物
八皇后问题,输出了所有情况,不过有些结果只是旋转了90度
2016/08/15 面试题
公务员个人自我评价分享
2013/11/06 职场文书
元宵晚会主持词
2014/03/25 职场文书
合作投资意向书
2014/04/01 职场文书
商业融资计划书
2014/04/29 职场文书
5.12护士节演讲稿
2014/04/30 职场文书
三八妇女节标语
2014/10/09 职场文书
二年级语文上册复习计划
2015/01/19 职场文书
保险公司客户经理岗位职责
2015/04/09 职场文书
大学学生会辞职信
2015/05/13 职场文书
元旦晚会主持词开场白
2015/05/28 职场文书
golang正则之命名分组方式
2021/04/25 Golang
python基于tkinter实现gif录屏功能
2021/05/19 Python