Javascript之旅——第八站:说说instanceof踩了一个坑
前些天写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 运算符深入剖析 转自:https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/ instanceof 运算符简介 在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 object 。
相关文章
- 用javascript写一个emoji表情插件
- JavaScript 最佳实践
- 看看国外的javascript题目,你能全部做对吗?
- 第一百三十二节,JavaScript,封装库--下拉菜单
- [Javascript] Create Your First Iterator in JavaScript
- [Poi] Build and Analyze Your JavaScript Bundles with Poi
- [Javascript] Javascript 'in' opreator
- 小白学 Python 爬虫(39): JavaScript 渲染服务 scrapy-splash 入门
- JavaScript HTML DOM 入门详解
- [Javascript] Safely Access a Property on a JavaScript Array with Optional Chaining
- [Javascript] Avoiding Mutations in JavaScript with Immutable Data Structures
- [TypeScript] Use the JavaScript “in” operator for automatic type inference in TypeScript
- [Javascript] Use JavaScript's for-in Loop on Objects with Prototypes
- [Javascript] Iterate Over Items with JavaScript's for-of Loop
- JavaScript点击事件-一个按钮触发另一个按钮
- 使用 JavaScript Promise 读取 Github 某用户的数据
- JavaScript ES6对Proxy的原生支持的一个例子
- 一个百度贴吧下载指定单个帖子所有回复的工具(JavaScript)实现
- 从零开始学_JavaScript_系列(14)——dojo(7)(饼图,BorderContainer,hashchange,弹窗)
- 【华为OD机试 2023】士兵过河(C++ Java JavaScript Python)
- 每天一个JavaScript实例-从一个div元素删除一个段落
- 每天一个JavaScript实例-推断图片是否载入完毕
- 每天一个JavaScript实例-动态省份选择城市
- Javascript 严格模式下不允许删除一个不允许删除的属性
- web前端Javascript学习之了解JavaScript弹出框
- 怎么创建 JavaScript 自定义事件
- javascript中!=、!==、==、===操作符总结