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

- alert(typeof null); // "object"
- alert(typeof []); // "object"
2、instanceof操作符。此操作符检测对象的原型链是否指向构造函数的prototype对象,恩,听起来不错,应该可以解决我们的数组检测问题:

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

- var arr = [];
- alert(arr.constructor == Array); // true
貌似后两个解决方案是无懈可击的,但真的是这样么?天有不测风云,当你在多个frame中来回穿梭的时候,令人沮丧的问题出现了:

- var iframe = document.createElement_x('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方法:

- isArray: function(object) {
- return object != null && typeof object == "object" &&
- 'splice' in object && 'join' in object;
- }
isArray:”object,你有splice、join这两个数组特有的方法吗?”
 object:“嗯,没错我有!”
 isArray:“好吧,那你就是个数组了,哪怕你是冒充的,囧……”

- var trickster = { splice: 1, join: 2 };
- Object.isArray(trickster); // 假冒成功,耶
没错,这个解决方案给人的感觉有点别扭,任何一个具有'splice'和'join'属性的对象都能通过这个检测!怎么办怎么办怎么办??别着
急,仔细想想,其实我们需要的是一个能取得对象实际类型,而且又能跨frame使用的方法即可。这不,细心的老外在翻阅ECMA262标准的时候发现了这
 个(btw,我也看了,怎么就没发现这个用途呢,囧):
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的描述吧:
new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”.
于是乎,可以改写之前的isArray函数以利用这个特性,如下:

- 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等等,都计划借鉴此方法以实现某些特殊的,比如数组、正则表达式等对象的类型判定,不用我们自己写了。
js isArray小结的更多相关文章
- Js继承小结
		Js继承小结 一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.n ... 
- [js]js设计模式小结
		js设计模式小结 工厂模式/构造函数--减少重复 - 创建对象有new - 自动创建obj,this赋值 - 无return 原型链模式 - 进一步去重 类是函数数据类型,每个函数都有prototyp ... 
- [js]设计模式小结&对原型的修改
		js设计模式小结 工厂模式/构造函数--减少重复 - 创建对象有new - 自动创建obj,this赋值 - 无return 原型链模式 - 进一步去重 类是函数数据类型,每个函数都有prototyp ... 
- 7-81 js课程小结
		7-81 js课程小结 学习要点 理解全局对象 变量的作用范围 理解全局对象Global 全局属性和函数可用于所有内建的 JavaScript 对象.全局对象是所有全局方法的拥有者,用来统一管理全局方 ... 
- JS系列——Linq to js使用小结
		前言:前面几篇介绍了下C#基础技术中的几个:反射.特性.泛型.序列化.扩展方法.Linq to Xml等,本来还有两三个知识点没有写完,比如委托.多线程.异步等,后面会陆续将它们补起来,以便作为一套完 ... 
- 老生常谈--Js继承小结
		一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.net/stoy ... 
- JS isArray、typeof、instanceof
		Array.isArray() 用来检验是不是数组 var a = [1,2,3] console.log(typeof a); // object console.log(Array.isArray ... 
- js分页小结
		今天解决了JS分页的问题1 页码 给每页的内容套一个相同的类名 通过选择器加上.length或者.size() 来获得总页数2当前页的页码可以使用each(function(index,DOMsss ... 
- js isArray
		function isArray(value) { if (typeof Array.isArray === "function") { return Array.isArray( ... 
随机推荐
- 我理解设计模式C++实现观察者模式Observer Pattern
			概述: 近期中国股市起起伏伏,当然了起伏就用商机,小明发现商机后果断想入市,买入了中国证券,他想在电脑client上,网页上,手机上,iPad上都能够查看到该证券的实时行情,这样的情况下我们应该怎么设 ... 
- DataGridView大扩展——显示行号
			原文 DataGridView大扩展——显示行号 在DataGridView 的实际使用中,经常需要标示出行号,这样可以比较醒目地看到当前信息.不过DataGridView 在绘制 DataGridV ... 
- 采用Sambaserver由win平台,linux平台上传文件
			1.构造yum [root@db /]# cd /etc/yum.repos.d/ [root@db yum.repos.d]# vi yum.repo --改动光盘挂载位置,enabled设置为启动 ... 
- 《Java程序猿面试笔试宝典》之Java与C/C++有什么异同
			Java与C++都是面向对象语言,都使用了面向对象思想(比如封装.继承.多态等),因为面向对象有很多非常好的特性(继承.组合等),使得二者都有非常好的可重用性. 须要注意的是,二者并不是全然一样,以下 ... 
- PowerCmd(转)
			PowerCmd 是一款Windows CMD 的增强工具,可以比普通CMD工具提供更多选项,例如: 1.多窗口集成,再也不见满屏的Cmd窗口: 2.命令日志记录,再也不怕命令滚动多快,有多少,我们都 ... 
- 【世外桃源】福音节目 swtychina.com
			[世外桃源]福音节目 今天小编满怀热情,带着激动地心情,颤抖的双手,以“大无畏的精神,高山仰止的情操”为大家郑重推荐很好的一个福音节目: <世外桃源>, 哎,不对,貌似从2013年初开始& ... 
- 【剑指offer】面试题28:弦乐
			def Permutation(data, i): if len( data ) == 0: return # i stand for the start of first part for i in ... 
- 1!到n!的和
			Time Limit: 1 Sec Memory Limit: 64 MB Submit: 23 Solved: 14 [Submit][Status][Web Board] Descriptio ... 
- jqm的多列布局demo,html5的多列布局demo,多列布局的具体解说,html5开发实例具体解释
			因为移动设备屏幕宽度较小,所以一般不建议使用多列布局.但有时你可能须要并排放置一些元素(如button之类的). jQuery Mobile通过约定的类名ui-grid来提供了一种基于css的多列布局 ... 
- Programming from the ground up(0)
			这本书的英文版是开源.我读了一些.但是,支持的英语水平不走太,然后还有那些谁译的书,但感觉不是太干脆翻译,在一些地方难以清除作者的思路,所以,我要揍很难理解他自己翻译一下原来的地方,这将更好地了解一点 ... 
