继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

eval()、with欺骗词法作用域

五月君
关注TA
已关注
手记 120
粉丝 7785
获赞 2338
欺骗词法作用域

词法作用域由写代码期间函数所声明的位置来定义,javascript有两种机制(eval()、with)在运行时来修改词法作用域,这样做通常会导致性能下降,内存泄漏问题。

eval函数接收一个字符串为参数,解析字符串生成代码并运行

function test(str, b){
    eval(str);

    console.log(a, b);
}

var a = 1;

test("var a = 3", 2); // 3 2

console.log(a); // 1

上面这段代码示例,eval调用的str相当于在test函数作用域内部声明了一个新的变量b,当console.log()在打印时会在foo函数内部找到a和b,将无法找到外部的a,因此最终输出结果是3和2,最外层a仍就输出是1,两者比较可以看到效果。

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

{
function withObj(obj){
    with(obj){
        a = 2
    }
}

let o1 = {
    a: 1,
}

let o2 = {
    b: 1,
}

withObj(o1);
console.log(o1.a); // 2

withObj(o2);
console.log(o2.a); // undefined
console.log(a); // 2
}

以上示例中withObj(obj)函数接受一个obj参数,该参数是一个对象引用,执行了with,o1传进去,a=2赋值操作找到了o1.a并将2赋值给它,o2传进去,因为o2没有a属性,就不会创建这个属性,o2.a保持undefined,这个时候就会创建一个新的全局变量a。

对性能的影响

javascript引擎在编译阶段会进行性能优化,很多优化依赖于能够根据代码词法进行静态分析,预先确定了变量和函数的定义位置,才能快速找到标识符,但是在词法分析阶段遇到了with或eval无法明确知道它们会接收什么代码,也就无法判断标识符的位置,最简单的做法就是遇到with或eval不做任何优化,使用其中一个都会导致代码运行变慢,因此,请不要使用他们。

github地址 https://github.com/Q-Angelo/summarize/blob/master/nodejs/base.md

打开App,阅读手记
2人推荐
发表评论
随时随地看视频慕课网APP