作用域主要有两种,一种为词法作用域 一种为动态作用域(Bash脚本等)
词法作用域就是定义在词法阶段的作用域
也就是你的变量和作用域写在哪里决定的。
function foo(a){
var b = a * 2
function bar(c){
console.log(a,b,c)
}
bar(b*3)
}
foo(2)
包含整个全局作用域的唯一标识是foo
包含foo所创建的作用域,表示:a,b. bar
包含Bar所创建的 只有c
欺骗词法
如果词法作用域完全由写代码期间函数声明的位置来定义。怎么样才能在运行时来 修改(也就是欺骗)词法作用域?
js里有两种机制可以实现这一目的。但是欺骗词法作用域可能会导致性能下降。
1.eval()
这个函数可以接受一个字符串作为参数。执行了eval(…)之后。引擎并不知道或者在意前面代码是以动态形式插入进来的。并会对词法作用域的环境进行修改。
默认情况下 eval(…)所执行的代码包含一个或者多个声明(无论是变量还是函数)
但是在严格模式的程序中,eval(…)在运行时有自己的词法作用域,意味着其中的声明无法修复所在的作用域
function foo(str){
"use strict"
eval(str)
console.log(a)
}
foo("var a = 2")
此时打印出来的a 会报错 ReferenceError:a is not defined
js中还有一些功能效果和eval类似,例如 setTimeout(),setInterval()
这些第一个参数可以是字符串,其内容可以呗解释为一段动态生成的函数代码。
new Function(…)函数行为也比较类似,最后一个参数可以是接受代码字符串。然后转化成动态生成的函数。比eval()稍微安全一些。
但是这些他能带来的好处无法抵消掉对性能的损失。
第二种方式 后续在更。