【《你不知道的JS(上卷①)》】二、词法作用域

二、词法作用域:

​ 作用域共有两种主要的工作模型。普遍被采用的的是第一种,词法作用域。另一种为 动态作用域,被Bash脚本、Perl中的一些模式所采用。

一)、词法阶段:

​ 第一章提到过编译阶段之一——词法分析。词法作用域就是定义在词法阶段的作用域,即词法作用域由你在写代码时将变量和块作用域写在哪里来决定的,大部分情况下词法分析器处理代码时会保持作用域不变。

遮蔽效应:

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

二)、欺骗词法:

​ 通常不应该使用这些词法,会造成安全问题以及性能变慢。

  1. eval:接受一个字符串为参数,并将其中的内容视为好像在书写时就存在与程序中这个位置的代码。

    function foo(str, a) {
    	eval(str);
    	console.log(a, b);
    }
    var b = 2;
    foo("var b = 3;", 1); // 1, 3
    
  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
    

    ​ 最后一步之所以会出现一个全局变量,是因为进行了一次LHS查询。而直接在外层作用域中对o2.a进行查询,当o2没有a属性时,并不会创建这个属性,而是保持undefined。

posted @ 2020-06-07 15:10  macguz  阅读(180)  评论(0编辑  收藏  举报