前几天,又是工作上的问题。发现一个对象实例在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中,typeof和instanceof是常用的两种检测数据类型的方式,它们各自有其适用的场景和特点。 ### typeof typeof 是一个一元运算符,它用于返回变量或表达式的类型。当使用typeof运算符时,它通常会返回...
ElectronJS instanceof bug 演示 这演示了在 Windows 上使用 ElectronJS 时 instanceof 的错误。 问题: : 运行测试 电子测试: npm run test-electron 节点测试: npm run test-node
虽然 typeof null 为 object,但这只是 JavaScript 存在的一个悠久 Bug,不代表 null 就是引用数据类型,并且 null 本身也不是对象。因此,null 在 typeof 之后返回的结果是有问题的,不能作为判断 null 的方法。...
因此,学习JavaScript还需要了解类型转换、类型检测、以及如何使用typeof和instanceof等操作符来避免类型相关的bug。 此外,JavaScript的异步编程能力也是一大亮点,它允许执行耗时的任务如网络请求或大量计算而不...
JavaScript是一种广泛使用的脚本语言,它在网页设计中...在编程实践中,了解和理解这些JavaScript的特殊行为对于避免写出有bug的代码至关重要。开发者应该时刻警惕这些陷阱,通过测试和代码审查来确保其代码的健壮性。
此外,`typeof null`返回`'object'`,这是JavaScript历史遗留的一个bug。`typeof`通常用于简单快速地检查基础类型,但对于复杂类型如对象和数组,其表现可能不尽如人意。 `instanceof`操作符: `instanceof`用于...
JavaScript是一种广泛用于网页和网络应用的编程语言,尤其在前端开发中扮演着核心角色。...JavaScript的动态类型和一些特性可能导致意外行为,因此深入理解这些知识点对于编写高效、无bug的代码至关重要。
在JavaScript编程中,正确检测变量或数据类型是常见的需求。...在实际应用中,合理使用类型检测可以避免很多因类型问题导致的bug,提高代码的可维护性和可读性。希望本文的内容能够对大家的学习和工作有所帮助。
比如在frameA里创建的对象me,如果传到frameB后,在frameB内使用instanceof检测Person,可能会返回false,因为JavaScript中的函数与对象都有自己的作用域,这一点在操作DOM元素时尤其要注意。 三、Function与Array...
- JavaScript 有七种原始类型:Undefined、Null、Boolean、Number、BigInt、String 和 Symbol。它们是不可变的,直接存储值。 - 特别地,Number类型包括整数和浮点数,JavaScript 使用IEEE 754标准表示,这可能...
在JavaScript中,数据类型检测的方法主要有两种:typeof运算符和constructor属性。 typeof运算符是最基本的类型检测方法,它可以用来检测除null之外的所有简单数据类型的类型。例如: ```javascript alert(typeof ...
总结一下,JavaScript中的类型判断涉及到`typeof`、`instanceof`、`Array.isArray()`以及`Object.is()`等多个工具。理解它们的用法和限制,对编写健壮的JavaScript代码至关重要。在处理复杂类型尤其是对象和数组时,...
// "object" (bug) console.log(typeof Symbol()); // "symbol" ``` 2. **instanceof**:此操作符用于检查一个对象是否在其原型链上具有给定的构造函数的`prototype`属性。它不适用于基本数据类型: ```...
- **3.4.1 类型检测:** 使用`typeof`或`instanceof`等方法进行类型检测。 - **3.4.2 类型转换:** 明确地进行类型转换操作,避免隐式转换带来的不确定性。 **3.5 字符串** - 使用模板字符串进行字符串拼接,提高代码...
但对引用数据类型,如数组、对象等,typeof返回的都是"object",这包括null也被认为是"object",这实际上是JavaScript的一个bug。instanceof操作符可用于检测某个对象是否是特定类的一个实例。然而,更好的方式是...
总的来说,理解JavaScript的基本类型与引用类型以及它们之间的差异和转换规则,对于编写高效且无bug的代码是必要的。开发者需要熟练掌握类型判断技巧,避免类型转换带来的意外行为,并在处理复杂数据结构时注意深...
如果需要区分这些类型的对象,可以使用instanceof运算符或Array.isArray()方法来辅助判断。 4. **Safari 5和Chrome 7之前的版本对正则对象返回'function'**: 在某些旧版本的Safari和Chrome浏览器中,typeof...