美文网首页
词法作用域

词法作用域

作者: 后发而先制 | 来源:发表于2017-07-24 09:41 被阅读0次

    词法阶段

    词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变(大部分情况下是这样的)。

    嵌套作用域

    function foo(a) {

    var b = a * 2;

    function bar(c) {

    console.log( a, b, c );

    }

    bar( b * 3 );

    }

    foo( 2 ); // 2, 4, 12

    标识符 foo() 作用域

    标识符 foo(a){} 作用域

    标识符 bar(c) 作用域

    欺骗词法

    eval () 函数可以接受一个字符串为参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。

    setTimeout(..) 和 setInterval(..) 的第一个参数可以是字符串,字符串的内容可以被解释为一段动态生成的函数代码。

    new Function(..) 函数的行为也很类似,最后一个参数可以接受代码字符串,并将其转化为动态生成的函数(前面的参数是这个新生成的函数的形参)。

    function foo(str, a) {

    eval( str ); // 欺骗!

    console.log( a, b );

    }

    var b = 2;

    foo( "var b = 3;", 1 ); // 1, 3

    with

    with 通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。

    with坑

    function foo(obj) {

    with (obj) {

    a = 2;

    }

    }

    var o2 = {

    b: 3

    };

    foo( o2 );

    console.log( o2.a ); // undefined

    console.log( a ); // 2——不好,a 被泄漏到全局作用域上了!

    o2中没有a 放入with中后 无法赋值  a=2就会变为全局变量 通过LHS来查找滴话。

    性能

    eval(..) 和 with 会在运行时修改或创建新的作用域,以此来欺骗其他在书写时定义的词法作用域。

    JavaScript 引擎会在编译阶段进行数项的性能优化。其中有些优化依赖于能够根据代码的词法进行静态分析,并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。

    最悲观的情况是如果出现了 eval(..) 或 with,所有的优化可能都是无意义的,因此最简单的做法就是完全不做任何优化。

    相关文章

      网友评论

          本文标题:词法作用域

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