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

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

定是Array类型。

一:抛出问题

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

Index.html页面

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body> <iframe name="childframe" src="Flight.html"></iframe> <script type="text/javascript"> window.onload = function () {
//航班
var airplanes = ["MU", "CA", "CZ"]; var result = window.frames[0].flight.SearchFlight(airplanes);
};
</script>
</body>
</html>

Flight.html页面

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script type="text/javascript"> var flight = (function () { return {
SearchFlight: function (arr) {
var result = arr instanceof Array;
alert(result);
}
};
})();
</script>
</body>
</html>

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

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

         var flight = (function () {

             return {
SearchFlight: function (arr) {
//var result = arr instanceof Array; var result = arr.constructor == Array; alert(result);
}
};
})();

从图上看,还真有点奇怪,明明都是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的内

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

最新文章

  1. iOS 3D Touch 适配开发
  2. chmod权限设置
  3. jQuery的$.ajax示例
  4. windows-ubuntu环境变量的设置格式的不同
  5. 传说中的WCF(7):“单向”&amp;“双向”
  6. configure文件中判断某函数或库是否存在的一个方法
  7. linux 0.11 源码学习+ IO模型
  8. C++中的string
  9. 在web page中使鼠标右击失效的几种方法
  10. linux于test 订购具体解释
  11. 双端链表--Java实现
  12. CSS速查列表-1-(background)背景
  13. spring-oauth-server实践:access_token的有效期分析
  14. 《javascript语言精粹》读书笔记 Item1 精华与语法
  15. 爬虫(三)http和https协议
  16. Linux常用指令之二
  17. C#执行javascript代码,执行复杂的javascript代码新方式
  18. python for dblp.xml
  19. Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
  20. 架构师速成7.3-devops为什么非常重要

热门文章

  1. iOs 自定义UIView 日历的实现 Swift2.1
  2. 实现在ios开发中的App滑动封面 UIScrollView
  3. CARP
  4. springMVC分页,interceptor实现
  5. Servlet与多线程与IO操作
  6. String和StringBuffer的区别
  7. 通过angularJS官方案例快速入门
  8. AngularJS结合RequireJS做文件合并压缩的那些坑
  9. chrome developer tool—— 断点调试篇
  10. ArcGisServer根据最大最小坐标换算瓦片行列号