前些天写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的内

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

Javascript之旅——第八站:说说instanceof踩了一个坑的更多相关文章

  1. (转)Sql Server之旅——第八站 复合索引和include索引到底有多大区别?

    索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的 索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇 ...

  2. Javascript之旅——第十一站:原型也不好理解?

    写到这篇,我的js系列也快接近尾声了,所以这个系列不会遗留js来实现面向对象的核心——原型,有些人说原型不好理解,其实嘛,要想系统 的理解原型,最便捷的方式就是看看经典的书,少看些博客,博客这东西只是 ...

  3. Javascript之旅——第十站:为什么都说闭包难理解呢?

    研究过js的朋友大多会说,理解了js的原型和闭包就可以了,然后又说这些都是js的高级内容,然后就又扯到了各种神马的作用域...然后不少 人就会被忽悠的云里雾里...下面我也试着来说说闭包,看我说的这个 ...

  4. Javascript之旅——第七站:说说js的调试

    最近比较吐槽,大家都知道,现在web前端相对几年前来说已经变得很重了,各种js框架,各种面对对象,而且项目多了,就会提取公共模块, 这些模块的UI展示都一样,不一样的就是后台逻辑,举个例子吧,我们做企 ...

  5. Javascript之旅——第五站:说说那些所谓的包装类型

    最近不看犀牛书了,那本翻译的特烂而且好拗口,尤其是原型那块说的乱七八糟,后来经同事介绍,买了本js高级程序设计,然后就继续 苦逼的看,不吐槽了,继续说说js中有新鲜感的包装类型. 一:String 说 ...

  6. Javascript之旅——第四站:parseInt中要注意的坑

    前些天信用卡站点要接入一个新功能,不过还真比较坑爹,asp站点,大家都知道信用卡的背面是有一个有效期的,在对接银行中这个信息 一定是要传给银行做数据校验,用户在语音输入信用卡有效期后,系统会做一个有效 ...

  7. Sql Server之旅——第八站 复合索引和include索引到底有多大区别?

    周末终于搬进出租房了,装了宽带....才发现没网的日子...那是一个怎样的与世隔绝呀...再也受不了那样的日子了....好了,既然网 安上去了,还得继续我的这个系列. 索引和锁,这两个主题对我们开发工 ...

  8. Javascript之旅——第六站:看看writable特性

    说起js中的那些特性标记,总觉得有些怪怪的,那为什么要说到这个attribute,起源于对一个问题的疑问,我们都知道window对象其实就是 浏览器窗口的一个实例,既然是一个实例,那这个实例就应该有“ ...

  9. Javascript之旅——第三站:几个需要注意的运算符

    平时写惯了C#,所以会觉得什么样的运算符就应该做什么样的运算,但是有一天你的习惯被其他语言颠覆了,不知道是不是有一股强大的好奇 心,刚好在js中,我的这种习惯就被颠覆了,下面就看看哪些运算符颠覆了我的 ...

随机推荐

  1. .NET vs2010中使用IrisSkin2.dll轻松实现winForm窗体换肤功能

    IrisSkin2.dll是一款很不错的免费皮肤控件,利用它可以轻松的实现winForm窗体换肤! 网上很多朋友说在VS2010中不能使用IrisSkin2.dll,我这里提供一个取巧的办法. Iri ...

  2. 【Java每日一题】20161024

    20161021问题解析请点击今日问题下方的"[Java每日一题]20161024"查看 package Oct2016; public class Ques1024 { publ ...

  3. GJM : Unity3D 常用网络框架与实战解析 【笔记】

    Unity常用网络框架与实战解析 1.Http协议          Http协议                  存在TCP 之上 有时候 TLS\SSL 之上 默认端口80 https 默认端口 ...

  4. mesos 学习笔记1 -- mesos安装和配置

    参考资料: 官方文档:http://mesos.apache.org/documentation 中文翻译:http://mesos.mydoc.io/ GitHub:https://github.c ...

  5. Virtual Box和Linux的网络配置盲记

    近来可能在虚拟机重装了Linux的缘故,在用yum安装软件时出现错误,在提示上连接镜像网站时,都是"linux counldn't resolve host"这样的提示.我估计是l ...

  6. java对cookie的操作

    java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题. 建立一个无生命周期的cookie,即随着浏览器的关闭即 ...

  7. go语言常用函数:copy

    数组切片内容复制 用于将内容从一个数组切片复制到另一个数组切片.如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行复制. slice1 := [], , , , } slice ...

  8. React入门--------顶层API

    React.createClass 参数:config(object) 创建一个ReactClass(组件类),参数是一个对象且必须带有render属性方法,该方法必须返回一个封闭的容器(容器内可以由 ...

  9. angular源码分析:图解angular的启动流程

    今天做了一些图来说明angular,由于angular实在太复杂了,不知道用什么图表示比较好,所以就胡乱画了一些,希望有人能看得懂. 一.源码文件编译合并顺序图 二.angular.module函数功 ...

  10. Android 多媒体播放API简介

    本文调用android的媒体播放器实现一些音乐播放操作 项目布局: <LinearLayout xmlns:android="http://schemas.android.com/ap ...