浅谈Javascript中的eval与with

开发 前端
Javascript的作用域是词法作用域(lexical scope or static scope),也就是说作用域链在定义的时候就确定了。也提到eval、with会扰乱作用域链(dynamic scope)。

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(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='';

【编辑推荐】

  1. Javascript中的replace方法与正则表达式讲解
  2. 详解Javascript trim()函数实现
  3. 应用最广的十大Javascript框架
责任编辑:彭凡 来源: kaima.cnblogs.com
相关推荐

2009-07-31 13:48:34

C# eval()函数

2021-07-16 07:57:35

JavaScriptEval函数

2017-08-28 15:21:29

异步处理回调函数异步编程

2017-08-22 16:40:22

前端JavaScript接口

2009-06-10 22:06:29

JavaScript面向对象

2015-05-18 13:51:08

2020-12-07 06:38:32

JavaScriptEval 函数

2011-07-14 10:58:26

JavaScript强制类型转换函数

2013-03-26 10:27:01

JavaScriptjson

2009-04-21 09:37:50

ASP.NETAjaxJavaScript

2009-06-18 12:21:07

javascriptdom

2009-06-24 10:49:16

JavaScript

2014-07-24 10:00:21

2015-12-02 11:06:20

2015-05-06 10:02:26

2013-12-04 14:19:40

JavaScript代码重用

2016-09-18 20:53:16

JavaScript闭包前端

2009-06-24 15:00:39

Javascript代

2011-09-26 10:50:16

JavaScript

2009-06-09 11:37:51

ViewStateViewDataASP.NET
点赞
收藏

51CTO技术栈公众号