美文网首页JS让前端飞前端开发那些事
你不知道的JavaScript:词法作用域

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

作者: FeRookie | 来源:发表于2017-07-25 23:28 被阅读21次
词法作用域

简单的说,词法作用域就是定义在词法阶段的作用域。词法作用域就是由你写代码时将变量和块作用域写在哪里来决定的。因此当词法解析器处理代码时会保持作用域不变。

function foo(a){
  var b = a*2;

  function bar(c){
    console.log(a,b,c);
  }
  bar(b*3)
}

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

如上例子中有三层嵌套的作用域:

  1. 包含整个全局作用域,其中只有一个标识符:foo;
  2. 包含着foo所创建的作用域,其中有三个标识符:a,b,bar;
  3. 包含着bar所创建的作用域,其中只有一个标识符:c;

将每个作用域看成是一个气泡,作用域气泡由其对应的作用域块代码写在哪里决定的,他们之间是逐级包含

查找

作用域气泡的结构和互相之间的位置关系给引擎提供了足够的位置信息,引擎用这些信息来查找标识符的位置。作用域查找会在找到第一个匹配的标识符或停止。
在多层嵌套的作用域中可以定义同名的标识符,这叫做“遮蔽效应”

无论函数在哪里调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。

欺骗词法

前面说过关于词法作用域是在你写代码时,根据函数声明的位置来定义的,那么在运行的时候是否有办法来“修改”词法作用域呢。

欺骗词法作用域有两种机制,但是这样会导致性能下降,下面我们来看看这两种机制分别是什么吧。

  • eval
    eval函数可以接受一个字符串参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。简而言之就是在你调用eval的地方生成代码并执行。
function foo(str, a){
  eval(str); //欺骗词法
  console.log(a, b);
}
var b = 2;
foo("var b=3;", 1); //   1, 3

如上例子,eval的调用会在当前的位置执行其中代码,所以会在那里执行var b=3; 那么会屏蔽掉全局作用域中的var b=2;这样输出的值是1,3。

在严格模式中,eval会有自己的作用域,这就意味着其无法修改所在的作用域。

  • with
    with关键字的作用是将代码的作用域设置到一个特定的对象中。
var obj={
  a:1,
  b:2,
  c:3
}
with(obj){
 a=3;
 b=4;
 c=5;
}

  • 性能
    JavaScript引擎会在编译阶段进行数项的优化。其中部分优化是根据代码的词法进行静态分析,并预先确定所有变量和函数的位置,才能在执行过程中快速找到标识符。
    但是如果使用了eval和with,它只能简单的假设关于标识符位置的判断都是无效的。因为无法在词法分析阶段知道他们接受到的是什么。

相关文章

  • 词法作用域

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

  • 2.词法作用域

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

  • 「JS」变量作用域

    作用域介绍静态作用域动态作用域 JavaScript 变量作用域词法环境组成创建结构关于词法环境的问题with 语...

  • JavaScript作用域和变量提升

    一、JS的作用域 1.JS采用词法作用域 首先,我们得知道JavaScript采取的是词法作用域,而不是动态作用域...

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

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

  • JavaScript this 绑定规则

    JavaScript 中的作用域是词法作用域。而JavaScript中的 this 却更加类似于 动态作用域的机制...

  • JavaScript 之 静态作用域与动态作用域

    静态作用域 JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 函数的作用...

  • 一网打尽 JavaScript 的作用域

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。 全局作用域 在任何...

  • javascript基础知识问答-作用域和闭包

    1.理解词法作用域和动态作用域2.理解JavaScript的作用域和作用域链3.理解JavaScript的执行上下...

  • JavaScript深入系列的学习(一)

    JavaScript深入之从原型到原型链JavaScript深入之词法作用域和动态作用域JavaScript深入之...

网友评论

    本文标题:你不知道的JavaScript:词法作用域

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