zoukankan      html  css  js  c++  java
  • javascript 中使用instanceof需要注意的一点

    javascript中的instanceof需要注意的一点:

    当跨页面传送对象的时候,可能会返回和预期不一样的结果。instanceof的原理是查找实例化对象的__proto__是否在构造函数的原型链上,如果是则返回true,否则false。

    来个示例:

    //   test.js文件

    1 function test (){
    2     this.name = 'evan';
    3 }

    //   child.html

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8" />
     5     <title></title>
     6     <script src="test.js"></script>
     7     <script>
     8         document.evalData = eval("({obj: new test})");
     9         document.data = "{obj: new test}";
    10     </script>
    11 </head>
    12 <body>
    13 
    14 </body>
    15 </html>

    //   parent.html

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8" />
     5     <title></title>
     6     <script src="test.js"></script>
     7 </head>
     8 <body>
     9     <iframe src="child.html" frameborder="0" id="iframe"></iframe>
    10     <script>
    11        window.onload = function(){
    12             var iframe = document.getElementById('iframe');
    13             var doc = iframe.contentWindow.document;
    14             (function fn(){
    15                 if( !doc ){
    16                     setTimeout(fn, 0);
    17                 } else {
    18                     doc.data = eval('(' + doc.data + ')');
    19 
    20                     console.log(doc.evalData.obj instanceof test);
    21                     console.log(doc.data.obj instanceof test);
    22                  }
    23             })();
    24         }
    25     </script>
    26 </body>
    27 </html>

    console.log(doc.evalData.obj instanceof test); 结果是false
    其实从逻辑上一看它本身就是不应该这样做的,doc.evalData的数据已经在child页面中使用eval转换成javascript代码了,所以new test是在child页面的运行环境下运行的。

    而parent页面引用了这个对象,然后用instanceof来检测是否是当前parent的运行环境中的test构造函数的实例化对象,两个独立运行环境执行的代码怎么可能相同呢。

    console.log(doc.data.obj instanceof test); 结果是true
    它实例化data的数据是在当前页面实现的,即

    doc.data = eval('(' + doc.data + ')');

    而其中 new test引用的是当前执行环境(parent页面)中的test构造函数,所以这是合理的。

    每一个页面都会创建一个新的执行环境,iframe也不例外。
    浏览器在执行script的时候会把所有脚本都装载到一个全局环境中,所以这里的test构造函数在script执行时会装载到当前全局环境中。
    所以当前全局环境中构造函数的原型链上不可能有另一个全局环境中对象的__proto__

    随笔记录,不对的地方请园子里的大神多多指正

  • 相关阅读:
    JLable设置复制粘贴
    JLable设置背景颜色
    JFrame 居中显示
    String、StringBuffer、StringBuiler区别
    java读取本地文件
    mybatis 添加后获得该新增数据自动生成的 id
    验证身份证号规则(验证身份证号是否正确)
    MyBatis like (模糊查询)
    MyBatis if test 传入一个数字进行比较报错 There is no getter for property named 'userState' in 'class java.lang.Integer'
    Redis 中 byte格式 写入、取出
  • 原文地址:https://www.cnblogs.com/Evan2z/p/3317065.html
Copyright © 2011-2022 走看看