美文网首页
第一部分 第2章 词法作用域

第一部分 第2章 词法作用域

作者: 酥枫 | 来源:发表于2018-10-14 13:00 被阅读0次

词法作用域

词法作用域
  • 作用域查找会在找到第一个匹配的标识符时停止,内部标识符会屏蔽同名外部标识符。

  • 全局变量会自动成为全局对象(比如window或global),但这里有点小小的区别:

    var a=1;
    b=2;
    function(){
        var c=3;
        d=4;
    }
    

    若上面代码在浏览器中,全局对象是window,a,b,d都会成为window的属性,即均可以通过window.a访问(非严格模式下,严格模式下不通过var声明会报错)。
    若上面的代码在vscode中,全局对象是global,只有b,d会成为global的属性(非严格模式下,严格模式下不通过var声明会报错),global不会自动把用var声明的变量添加为自己的属性。

欺骗词法

词法作用域完全由写代码期间函数所声明的位置来定义,通过欺骗词法可以在运行时修改词法作用域,但是会导致性能下降。

  • eval(...)函数(在严格模式或ES6中被限制,不建议使用)
    接受一个字符串参数,可以在你写的代码中用程序生成代码并运行,就好像代码是写在那个位置一样。如:

    function foo(str,a){
        eval(str);
        console.log(a,b);
    }
    var b=2;
    foo("var b=3;",1);//1 3
    

    eval(...)通常用来执行动态创建的代码。

  • with关键字(在严格模式或ES6中被禁止使用)
    with通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。

    function foo(obj){
        with(obj){
            a=3;
        }
    }
    var o1={a:2};
    var o2={b:2};
    foo(o1);
    foo(o2);
    console.log(o1.a);//3
    console.log(o2.a);//undefined
    console.log(a);//3
    

    在上面的代码中,with会在代码执行时动态地延长作用域链(另外一个延长作用域链的方法是try-catch语句块中的catch块),因为o2没有a属性,所以通过LHS查询,引擎在全局环境创建了一个变量a并将3赋值给a,所以o2.a为undefined。

    这里有个要注意的问题就是,访问变量和访问对象的属性是不一样的:

    1. 访问变量时会LHS查询和RHS查询,在嵌套的作用域链中查询。
      赋值或者取值分别按照第一章所说的规则进行LHS查询和RHS查询
    2. 访问对象的属性则是通过对象的[[Put]]操作和[[Get]]操作来查找,在整个原型链([[prototype]]链)查找
      赋值时,通过[[Put]]操作,若变量存在则将新的值赋值给变量(实际上情况很复杂,详见第二部分第2章和第5章,p.117),若不存在,则为该对象创建该属性变量并赋值;取值时,通过[[Get]]操作取,若没有找到则遍历原型链,还是没有找到则返回undefined。

    所以上面代码改成下面的就会输出不同结果:

    function foo(obj){
        obj.a=3;
    }
    var o1={a:2};
    var o2={b:2};
    foo(o1);
    foo(o2);
    console.log(o1.a);//3
    console.log(o2.a);//3
    console.log(a);//ReferenceError: a is not defined(即a未声明undeclared)
    

相关文章

  • 你不知道的javascript(上券)

    第一部分 第2章 什么是词法作用域?动态作用域?js所采用的作用域模型是哪种?首先什么是作用域,简单来说就是限定一...

  • 词法作用域&动态作用域

    词法作用域(静态作用域) 词法作用域也叫静态作用域,jsvascript为词法作用域。词法作用域关心的是你的函数申...

  • 词法作用域

    我们知道JavaScript并不具有动态作用域,它只有词法作用域,什么是词法作用域? 一、 词法作用域 词法作用域...

  • 2.词法作用域

    JavaScript的作用域模型采用的是词法作用域 词法阶段 查找 欺骗词法作用域 既然词法作用域完全由编写时来决...

  • js中的作用域

    作用域就是决定变量有效范围 作用域按决定的时期来区分可分为词法作用域和动态作用域词法作用域: 词法作用域就是作用域...

  • JS基础-作用域与闭包

    1.理解词法作用域和动态作用域 词法作用域:定义在词法阶段的作用域换言之,词法作用域是由你在写代码时将变量和块作用...

  • 你不知道的JavaScript:词法作用域

    词法作用域 简单的说,词法作用域就是定义在词法阶段的作用域。词法作用域就是由你写代码时将变量和块作用域写在哪里来决...

  • 2、词法作用域

    词法作用域 简单地说,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写...

  • 词法作用域

    作用域工作模式:1 词法作用域;2 动态作用域(Bash脚本、Perl中的一些模式) 2.1 词法阶段 词法作用域...

  • 你不知道的 Javascript

    作用域 词法作用域:编译阶段确定(欺骗词法作用域 eval with) 块作用域 with try/catch l...

网友评论

      本文标题:第一部分 第2章 词法作用域

      本文链接:https://www.haomeiwen.com/subject/wsmzaftx.html