`

JavaScript的instanceof有bug?

阅读更多

前几天,又是工作上的问题。发现一个对象实例在instanceof XXX的时候,竟然返回了false,看看对象的内部结构,明明跟XXX的内部定义一样的。于是乎开始怀疑instanceof是不是有bug了,因为之前在创建一数组,在调了一圈之后,instaceof Array竟然也是false。不过后来阿飞调试之后,发现完全是因为跨页面传递了对象导致的。。。现将问题重现一下:

1、创建一个页面outer.html,并添加一个iframe

<iframe align="center" border="1" width="70%" title="Woo~" height="50%" src="bottom.html" name="bottom">aha~</iframe>

2、创建bottom.html页面

3、 添加outer.js文件,用来获取frame里边的页面,获取界面hanlder实例,并向其中传递数据

Ext.onReady(function() {
	var btmHandler;
	var fn = function() {
		btmHandler = window.frames["bottom"].document.handler;
		if (!btmHandler) {
			//iframe里边的页面还没有初始化完毕,就轮询,直到里边的页面装载完毕
			setTimeout(fn, 300);
		} else {
			//store instanceof Ext.data.Store: false
			var value1 = "({nickname:'maitian',store:new Ext.data.ArrayStore()});"
			btmHandler.accept(eval(value1));
			btmHandler.showInfo();

			//store instanceof Ext.data.Store: true
			var value2 = "{nickname:'maitian',store:new Ext.data.ArrayStore()}"
			btmHandler.accept(value2);
			btmHandler.showInfo();
		}
	};
	fn();

});

 4、为bottom.html创建 相应的js文件,并添加相关代码:

function BottomHandler() {
	this.name = 'Bottom';
	this.data = {};
};
BottomHandler.prototype = {
	constructor : BottomHandler,
	accept : function(value) {
		if (Ext.isString(value)) {
			value = eval('(' + value + ');');
		}
		if (Ext.isObject(value)) {
			Ext.apply(this.data, value)
		}
	},
	showInfo : function() {
		alert("store instanceof Ext.data.Store: "
				+ (this.data.store instanceof Ext.data.Store));
	}
};
Ext.onReady(function() {
			var hanlder = document.getHandler();
		});

document.getHandler = function() {
	if (!document.handler) {
		document.handler = new BottomHandler();
	}
	return document.handler;
};

 

5、创建完后,运行,会发现两个弹出框的结果,一个为false,一个为true。instanceof的内部机制是:每个实例都有__proto__隐藏属性,instanceof的时候会拿实例的__proto__属性与构造函数的prototype比较是否相同,如果一个对象是在A页面创建的,然后拿到B页面上,判断是不是某个构造函数的实例,就会发现返回false,因为prototype本质上也是一个Object,不同js虚拟机上创建的两个对象,怎么也不可能相同的。

6、解决办法:

  a、像本例一样,跨页面传递数据的时候,只传字符串,传过去后再eval

  b、像Ext.isArray实现一样,判断对应的字符串是否相等(Object.prototype.toString.call(inst) == '[object Array]'),但是对于所有自定义的构造函数的实例,都返回的是"[object Object]"。所以只有为没个自定义的构造函数都创建一个clazzType属性,用来判断实例的这个属性。当然这个不能解决别人已经创建的对象,或者已有框架,所以不是完美的解决办法。

分享到:
评论

相关推荐

    javascript instanceof 与typeof使用说明

    typeof用以获取一个变量的类型,typeof一般只能返回如下几个结果... 如果我们希望获取一个对象是否是数组,或判断某个变量是否是某个对象的实例则要选择使用instanceof。instanceof用于判断一个变量是否某个对象的实例

    electron-instanceof-bug

    ElectronJS instanceof bug 演示 这演示了在 Windows 上使用 ElectronJS 时 instanceof 的错误。 问题: : 运行测试 电子测试: npm run test-electron 节点测试: npm run test-node

    JavaScript中instanceof运算符的使用示例

    主要介绍了JavaScript中instanceof运算符的使用示例,instanceof的使用是JavaScript入门学习中的基础知识,需要的朋友可以参考下

    深入剖析JavaScript instanceof 运算符

    主要介绍了深入剖析JavaScript instanceof 运算符,ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。,需要的朋友可以参考下

    【JavaScript源代码】JavaScript 手动实现instanceof的方法.docx

    JavaScript 手动实现instanceof的方法  1. instanceof的用法 instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。 function Person() {} function Person2() {} const usr = ...

    javascript instanceof 内部机制探析

    pig instanceof Pig&#41;; // =&gt; true function FlyPig() {} FlyPig.prototype = new Pig(); var flyPig = new FlyPig(); alert&#40;flyPig instanceof Pig&#41;; // =&gt; true 来看另一段代码: 代码如下: // 代码 2 ...

    javascript instanceof,typeof的区别

    aColors[0] instanceof String&#41;; //output “false”; [removed] 你要区分string 与 String的区别 aColors[0] 是 string值类型, 当然不是String的实例啦。参考下面代码 var aColors = [“red”, “green

    JavaScript中instanceof运算符的用法总结

    JavaScript中instanceof运算符是返回一个 Boolean 值,指出对象是否是特定类的一个实例。 使用方法:result = object instanceof class其中result是必选项。任意变量。object是必选项。任意对象表达式。class是必...

    实例讲解JavaScript中instanceof运算符的用法

    JavaScript中的instanceof运算符可以用来判断对象类型,而更重要的是instanceof能够判断对象的继承关系,这里我们就来以实例讲解JavaScript中instanceof运算符的用法

    JavaScript instanceof 的使用方法示例介绍

    判断一个变量的类型尝尝会用 typeof 运算符而他毕竟有些缺陷,就是无论引用的是什么类型的对象,它都返回object,这时就要用到instanceof来检测某个对象是不是另一个对象的实例

    instanceof关键字.md

    因为在项目中遇到了instanceof,因此总结了对instanceof关键字的理解,有需要的可以下载来看看。

    instanceof.js ES5的instanceof手写实现

    ES5的instanceof手写实现

    JS中typeof与instanceof的区别

    JS中typeof与instanceof的区别

    详解JavaScript中typeof与instanceof用法

    typeof用以获取一个变量或者表达式的类型而instanceof用于判断一个变量是否某个对象的实例,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧

Global site tag (gtag.js) - Google Analytics