javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS eval with作用域链

JavaScript中eval和with语句如何影响作用域链的深度探索

作者:控心crazy

这篇文章主要为大家介绍了JavaScript中eval和with语句如何影响作用域链的深度探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

在上篇文章中,我们介绍了深度剖析了作用域,并将其定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找。

上篇文章入口:JavaScript作用域深度剖析:从局部到全局一网打尽

而作用域一共分为两种:词法作用域 和 动态作用域, 而本篇文章我们将深入 词法作用域,让我们一起来了解一下吧。

词法阶段

简单来说,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里决定的。

上述代码作用域:

包含着整个全局作用域,其中只有一个标识符: foo

包含着 foo 所创建的作用域,其中有三个标识符: a、bar、b

包含着 bar 所创建的作用域,其中只有一个标识符:c

无论函数在哪里被调用,或如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。

function foo(a) {
var b = a * 2;
function bar(c) {
    console.log(a, b, c);
}
bar(b * 3);
}
foo(2); // 2 4 12

欺骗词法

JavaScript 有两种机制来实现这个目的。

eval(不推荐使用)

在执行 eval(...) 之后的代码时,引擎并不 知道 或 在意 前面的代码是否以动态形式插入进来的,并对词法作用域的环境进行修改的。引擎只会如往常地进行此法作用域查找。

function foo(str, a) {
eval(str); // 欺骗!
console.log(a, b); // 1 3
}
var b = 2;
foo("var b = 3;", 1);

严格模式下:eval(...)在运行时有着自己的词法作用域,意味着其中的声明无法修改所在的作用域。

function foo(str) {
'use strict';
eval(str);
console.log(a); // ReferenceError: a is not defined
}
foo("var b = 3;");

with(不推荐使用)

with 通常被当做重复引用同一个对象中多个属性的快捷方式。

var obj = {
a: 1,
b: 2,
c: 3
};
// 单调乏味的重复"obj"
obj.a = 2;
obj.b = 3;
obj.c = 4;
// 简单的快捷方式
with (obj) {
a = 3;
b = 4;
c = 5;
}

其实不仅仅是为了方便访问对象属性,例如:

function foo(obj) {
with (obj) {
    a = 2;
}
}
var o1 = {
a: 3
};
var o2 = {
b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2——不好,a 被泄漏到全局作用域上了!

 性能

小结

特殊字符描述:

以上就是JavaScript中eval和with语句如何影响作用域链的深度探索的详细内容,更多关于JS eval with作用域链的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文