zoukankan      html  css  js  c++  java
  • Javascript的eval、with

    上一篇向高级Javascript程序员阵营迈进:Javascript一些概念研究总结提到,javascript的作用域是词法作用域(lexical scope or static scope),也就是说作用域链在定义的时候就确定了。也提到eval、with会扰乱作用域链(dynamic scope)。

    eval

    IE下:运行eval()会受当前作用域限制,运行execScript()则无视当前作用域,直接在全局作用域下执行。

    Firefox下:eval()和window.eval()效果不一样,这很奇怪,毕竟FF下,eval==window.eval。前者会受当前作用域限制,后者无视当前作用域,在全局作用域下执行(相当于IE的execScript())。

    有人写了一篇比较通俗的,参考这篇文章

    with

    with会暂时修改作用域链。

    <script>
    function a(){
        with (b) { 
            ...
        }
    }
    a(); </script>

    函数a在定义的时候,就确定了a的作用域链,我们姑且认为这条链的最顶端是全局对象window。

    当函数a被执行的时候,javascript引擎生成了一个call object并将其添加到作用域链尾部上(window对象之后),语句运行到with(b)时,将b添加到作用域链的尾部,所以with之内的变量查找,就会优先从这条链的b上查找---> 然后从a的call object中查找---> 最后查找window。with内的语句执行完之后,作用域链恢复原状(b被移出作用域链)。

    以上就是例子代码运行时的微观世界。

    with是不被推荐的,因为他操作作用域链,导致with语句之前的变量查找路径变长,执行效率低下。

    有些人可能认为with能节省代码量,比如

    with(document.forms[0]){
        name.value='';
        address.value='';
        email.value='';
    }

    就能少写不少document.forms[0],
    其实定义一个局部变量取代with中的b也可以达到同样目的,效率也无损失。

    var c=document.forms[0];
        c.name.value='';
        c.address.value='';
        c.email.value='';
    
  • 相关阅读:
    对象访问方式
    GC回收的对象
    邮件工具类
    java内存区域
    RabbitMQ的安装
    Flask信号
    DBUtils数据库连接池
    Flask蓝图基本使用
    Flask中使用cookie和session
    Flask中的CBV
  • 原文地址:https://www.cnblogs.com/kaima/p/1408748.html
Copyright © 2011-2022 走看看