JavaScript中严格模式到底限制了eval什么?

文章目录

  • 在`JavaScript`中严格模式到底限制了`eval`什么?
    • 1、错误的研究代码:
    • 2、问题的发现:
    • 3、总结:

JavaScript中严格模式到底限制了eval什么?

背景:
在研究《JavaScript权威指南》这本书的时候,在eval()的那一章节中对一句话的理解模模糊糊的,对应的段落如下所示:

严格模式下,被求值的代码可以查询和设置局部变量,但是不能
在局部作用域中定义新变量或函数;

下面便好好的进行研究:
eval() 函数它会使用调用它的代码的变量的环境,也就是说,他会像本地一样查找变量的值、定义新变量和函数。
在看到这句话的时候,我以为,所有的定义变量的方式,都会将新定义的变量的作用域设置为当前调用的环境,所以,也就存在上述的那段话一直不明白的原因。下面看我之前犯错误的时候的实验的代码;

1、错误的研究代码:

此时的测试的环境是在node中;

> function afun(){let name = "afun function ";eval("let name_1 = 'Eval function inner '");return name}
undefined
> afun()
'afun function '
> function afun(){let name = "afun function ";eval("let name_1 = 'Eval function inner '");return name_1}
undefined
> afun()
Uncaught ReferenceError: name_1 is not defined
    at afun (REPL3:1:89)
>> afun()
'afun function '
> function afun(){let name = "afun function ";eval("name = 'Eval function inner '");return name}
undefined
> afun()
'Eval function inner '
>

我们发现,我们在eval()中定义的这个变量只拥有块作用域。其实在这里已经能够发现问题所在了。因为自此ES6之后引入的letconst都是属于拥有块作用域的。在这里,使用它们定义的变量无法先变量的值上升的调用eval()的环境中,而是在这个块作用域中的一个环境中。

2、问题的发现:

在反复的阅读了这一篇的文章之后,发现如下的一段话:

如果这个函数调用了eval("var y = 3;"),则会声明一个新局部变量y。
另外,如果被求值的字符串使用了let 或 const,则声明的变量或
常量会被限制在求值的局部作用域内,不会定义到调用环境中。

看到上述的这段话,好家伙,我悟了。

且看如下的实验:
【实验一】:检测上述这段话中,条件:在函数中调用 的必要性

> eval('var d = 100;let b = 300; const c = 400;');
undefined
> d
100
> b
Uncaught ReferenceError: b is not defined
> c
Uncaught ReferenceError: c is not defined
>

上述的这段代码是在全局变量下的操作;我们发现,只用使用var定义的变量才会将对应的作用域放在调用eval()的环境中。
下面,来进行新的测试:

> function testStrict(){eval("'use strict';var a = 100;");console.log("a: " + a);}
undefined
> testStrict()
Uncaught ReferenceError: a is not defined
    at testStrict (REPL4:1:77)
> function testStrict(){eval("var a = 100;");console.log("a: " + a);}
undefined
> testStrict()
a: 100
undefined
>

如上述的代码所示,'use strict' 限制的就是 eval() 在执行的字符串代码中 var 声明的变量的作用域提升到该操作调用的环境中这个情形;

3、总结:

果然,读书不可以偏概全,尤其是在阅读一些非常厚的经典书籍的时候,需要有耐性将其慢慢梳理,联系每章节之间的联系。