我们将“作用域”定义为一套规则,这套规则用来管理引擎如何在当前作用域及嵌套的子作用域中根据标识符名称进行变量查找。
作用域共有两种主要工作模型。第一种是最为普遍的“词法作用域”,第二种红“动态作用域”。JavaScript使用的是词法作用域。
大部分标准的语言编译器的第一个工作阶段是词法化。词法化的过程会对源代码中的字符进行检查。如果是有状态的解析过程,还会赋予单词语义。简单来说,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时,将变量和块级作用域写在哪里来决定的。eval和with会改变词法作用域。eval是可以插入语句到当前的代码中,with是创建了一个新的作用域。
因为JavaScript引擎会在编译阶段进行数项的性能优化。其中有些优化依赖于能够根据代码的词法进行静态分析,并预先确定所有变量和函数的定义位置,才能在执行过程中快速的找到标识符。但是如果遇到eval或者with,它只能假设关于标识符的假设是无效的。所以尽量不要使用eval和with。不过在ES6里面,默认了严格模式,eval和with的使用也做了限制。
网友评论