作用域之词法作用域

                 词法作用域


编译器第一工作阶段叫词法化,过程中会对源代码的字符进行检查,判断该词法单元是否独立,还是其他词法单元的一部分,这个过程是词法分析,会赋予单词语义。

词法作用域就是定义在词法阶段你的作用域。

如有三个逐级嵌套的作用域,把他们想象成几个逐级包含的气泡。其中函数中的参数是属于函数内部的作用域气泡的。

作用域气泡由其对应的作用域块代码写在哪里决定的。

      作用域气泡的结构和互相之间的位置关系给引擎提供了足够的位置关系,引擎用这些信息来查找标识符的位

置。

作用域查找会在找到第一个匹配的标识符时停止,在多层的嵌套作用域中可以定义同名的标识符,结果是内部的标识符遮蔽了外部的标识符。

如果在代码中引用了foo.bar.baz,词法作用域查找只会查找foo标识符,找到这个变量后,对象属性访问规则会分别接管对bar 和baz属性的访问。

   #欺骗词法作用域

分别有eval()和with();

  (1)eval()

接受一个字符串作为参数,里面的代码在书写阶段被视为程序中已经存在的代码,不接受编译器的编译,在引擎执行代码的时候碰到eval()时重新修改书写期的词法作用域,类似的还有定时器函数传入的字符串参数。

  (2)with()

 with声明实际上是根据传递给它的对象凭空的创建了一个全新的词法作用域。


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被泄漏到全局作用域上了!


注意:eval()和with()会在运行时修改或创建新的作用域,以此来欺骗其他在书写时定义的词法作用域。故此,javascript引擎会在编译阶段进行数项的性能优化,其中有些依赖于能够根据代码的词法进行静态分析,并预先知道所有变量和函数的定义位置,才能在执行过程中快速找到标识符。但是引擎在代码中发现了eval()或with(),它会假设关于标识符位置的判断都是无效的,因为无法再词法分析阶段明确知道eval()会接收到什么代码,故所有的优化可能都是无意义的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值