前些天写js遇到了一个instanceof的坑,我们的页面中有一个iframe,我在index页面中计算得到了一个array,然后需要传递到Flight页面

这个嵌套的iframe中的一个函数(SearchFlight)中,作为防御性编程,我需要在SearchFlight函数中进行参数检测,也就是判断过来的参数一

定是Array类型。

一:抛出问题

举个例子,下面有两个页面。

Index.html页面

 1 <!DOCTYPE html>
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <title></title>
5 </head>
6 <body>
7
8 <iframe name="childframe" src="Flight.html"></iframe>
9
10 <script type="text/javascript">
11
12 window.onload = function () {
13 //航班
14 var airplanes = ["MU", "CA", "CZ"];
15
16 var result = window.frames[0].flight.SearchFlight(airplanes);
17 };
18 </script>
19 </body>
20 </html>

Flight.html页面

 1 <!DOCTYPE html>
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <title></title>
5 </head>
6 <body>
7 <script type="text/javascript">
8
9 var flight = (function () {
10
11 return {
12 SearchFlight: function (arr) {
13 var result = arr instanceof Array;
14 alert(result);
15 }
16 };
17 })();
18 </script>
19 </body>
20 </html>

很惊讶的发现instanceof居然不能判断出arr是一个数组,其实我们用肉眼可以看到,压根它就是一个数组,但是为什么instanceof却判断不出来呢?

我们知道instancof其实是一个js语法糖,我就修改成简单点的,判断arr.constructor是否指向Array,于是我把关键字改成如下形式,再来看看看效果。

 1         var flight = (function () {
2
3 return {
4 SearchFlight: function (arr) {
5 //var result = arr instanceof Array;
6
7 var result = arr.constructor == Array;
8
9 alert(result);
10 }
11 };
12 })();

从图上看,还真有点奇怪,明明都是function Array(),为啥都不能相等呢?不过事实就摆在眼前,容不得狡辩,只能静下心来想一想,我们

知道Array在js是属于引用类型,既然不相等那就说明他们其实是两个引用,对不对,并且Array是挂在window下的一个属性,window属性

也就是一个窗口的实例,那就说明Index.html是一个window实例,Flight.html也是一个window实例,为了验证下,我们看看两个window

是否相等?

看完图后,答案就很明白了,以C#的思维考虑一下,既然大的window都不相等,里面的Array属性自然就不相等,终于问题是找到了,下面

怎么解决呢?

二:解决问题

1. length判断

 这个很容易想到,也是最简单的,我们知道每个数组都有length,所以可以简简单单的看length是否存在就可以了,但是这个也不是万无一失

的,我们知道function中有两个属性length和prototype,那这就有问题了。这样我会错误的把f认为是数组。

2.使用prototype的call方法来实现

这个方法有点巧妙,首先我们要知道,每一个function中都会有call方法和prototype属性,而js在Object.prototype中的tostring函数上做了一个

封装,就是调用tostring.call后,会返回[object constructorName]的字符串格式,这里的constructorName就是call参数的函数名,比如我们把

arr传进去,就会返回“[object Array]”字符串格式,这个方法也可以让我们巧妙的判断是否是Array,但是比较遗憾的是,我们看不到这个call的内

部实现,只能黑盒的记住了。

javascript 为啥不用instanceof检测数组,这里有一个示例坑的更多相关文章

  1. JavaScript学习笔记:检测数组方法

    检查数组的方法 很多时候我们需要对JavaScript中数据类型(Function.String.Number.Undefined.Boolean和Object)做判断.在JavaScript中提供了 ...

  2. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  3. 在JavaScript中,如何判断数组是数组?

    如果你没有注意过这个问题,那么这个标题应该会让你感到困惑,判断数据类型这么基础的问题能有什么坑呢? 少年,你不能太天真了,我们朝夕面对的这门语言,可是JavaScript呀,任何你觉得已经习以为常的东 ...

  4. javascript篇-typeof,instanceof,constructor,toString判断数据类型的用法和区别

    javascript基本数据类型有:string,number,Boolean,undefined,null 引用类型(复杂类型):object, ES6中新增了一种数据类型:Symbol 以上数据类 ...

  5. JavaScript如何判断变量是数组还是对象

    编辑 方法一:通过判断变量的类型,并且变量的length属性(除了有一种例外是arguments对象–当给函数传参时数据存储的地方) var arr=[2,3,4]; var obj={"n ...

  6. JS高程5.引用类型(3)Array类型-检测数组

    1. instanceof操作符(ECMAScript3) 对于一个网页,或者是一个全局作用域而言,使用instanceof操作符来检测数组就可以得到满意的结果. 语法:if(value instan ...

  7. JavaScript类型判断instanceof与typeof对比

    经常有人会在JavaScript里写如下的方法: function checkType() { var s1 = 123; var s2 = "OK"; if (s1 instan ...

  8. 前端笔记之JavaScript(五)关于数组和字符串那点事

    一.数组 1.1数组概念 数组(array)是一个有序的数据集合.说白了,数组就是一组数.数组内部可以存放一个或多个单独的数据,整体组成数组. 定义数组最简单的方式:数组字面量. 数组的字面量“[]” ...

  9. JS_高程5.引用类型(3)Array类型-检测数组

    1. instanceof操作符(ECMAScript3) 对于一个网页,或者是一个全局作用域而言,使用instanceof操作符来检测数组就可以得到满意的结果. 语法:if(value instan ...

随机推荐

  1. Linux性能监测:CPU篇(转)

    http://os.51cto.com/art/201012/239880.htm CPU 的占用主要取决于什么样的资源正在 CPU 上面运行,比如拷贝一个文件通常占用较少 CPU,因为大部分工作是由 ...

  2. iOS开发tableview二级联动的细节实现中注意的细节总结

    首先说网络慢带来的数据显示问题 可以通过判断请求参数是否一致来刷新tableview. SJBCategaryModel * categaryModel = self.categarys[Catega ...

  3. Date 和 SimpleDateFormat 类表示时间

    Date now=new Date(); // 使用format()方法将日期转换为指定格式的文本 SimpleDateFormat sdf1 = new SimpleDateFormat(" ...

  4. phpstrom 快捷使用方式

    file-settings--key map键映射-->collapse(代码折叠)---- ctrl (减减)2次全部折叠  (加加)2次全部展开 格式化代码  ctrl+alt+L 替换 c ...

  5. Trouble Shooting

    情况是这样的,我在写一个类似于Online-Judge的系统,用python很容易实现,编译源程序,运行程序,最后比较程序输出与标准输出得出成绩.现在有个问题,万一程序运行时崩溃,比如出现除0异常,a ...

  6. ZUFE 1035 字符宽度编码(字符串)

    Time Limit: 1 Sec  Memory Limit: 128 MB Description 你的任务是编写一个程序实现简单的字符宽度编码方法.规则如下:将任何2~9个相同字符的序列编码成2 ...

  7. chapter11_2 Lua链表与队列

    链表 由于table是动态的实体,所以在Lua中实现链表是很方便的.每个节点以一个table来表示,一个“链表”只是节点table中的一个字段. 该字段包含了对其他table的引用.例如,要实现一个基 ...

  8. webpy 开发环境搭建问题之Mysql-python安装

    关于python核心编程已经看了差不多,准备搞些框架方面的学习,本来想打算看看Django的,但是朋友推荐先看看轻量级的flask或者webpy的开发,所以晚上回来,搭建下开发环境(PS:搭建过程中由 ...

  9. C# 验证码生成(MVC和非MVC两种方式)

    /// <summary> /// 生成验证码 /// </summary> /// <param name="length">指定验证码的长度 ...

  10. Virtual Drive Manager V1.3.2(小巧实用的虚拟光驱)绿色版

    软件名称: Virtual Drive Manager V1.3.2(小巧实用的虚拟光驱)汉化绿色修正版软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 ...