美文网首页
你不知道的JS:作用域是什么?

你不知道的JS:作用域是什么?

作者: 井润 | 来源:发表于2019-10-25 00:30 被阅读0次

前段时间一直想抽空把《你不知道的JS》给看一看,准备好好巩固JS的基础,于是现在有了这篇文章.

1.两个问题

  • 为什么讲作用域?
    • 讲作用域是因为大多数编程语言中,作用于都是非常关键的一环,它所提供的功能给我们编程程序的时候带来极大的便利!
  • 作用域在JS中的作用是什么?
    • 一套良好的规则来存储变量,并且与此同时,可以方便的找到变量,这套叫做作用域!

看到这里的你,是不是以为现在就已经将我要讲的内容已经简单阐述完了,其实不是的,讲到这里其实是为了我们更好地理解作用域而做的铺垫.

2.编译原理

在我们学习JavaScript的过程中,常常看到书中提到几个比较鲜明的字眼,动态类型,解释型的编程语言!但是在本文中,我要说的是,JavaScript是一门编译类型的语言,尽管和你看到的Java等常见的编译类型语言不同!

  • 并非提前编译
  • 编译后的结果不能够在分布式中进行移植

这两点适合传统的编译类型语言所不同的!虽然说JavaScript引擎编译和传统的编译语言步骤非常相似,但是在某些环节中比预想的还要复杂!

传统编译语言流程中在执行前会经历的三个步骤,称为"编译"

st=>start: start
op1=>operation: 1.分词/词法解析
op2=>operation: 2.解析/语法解析
op3=>operation: 3.代码生成
e=>end: end
st->op1->op2->op3->e
01编译.png

那么对应的流程图中的概念如何理解呢?

其实对应的也就是三个概念,我也只是结合自身的理解和书中的观点,进行简单阐述:

  • 分词/词法分析
    • 该过程会将字符串分割成为有意义的代码块! 至于说空格是否有意义,取决于空格在编程语言中是否有意义!
    • 其中有意义的代码块被称之为 词法单元!
  • 解析/语法分析
    • 该过程会将词法单元流(组)转换成为一个元素逐级嵌套组成代表程序语法结构的树!
    • 该树 被程序员们称之为 AST(Abstract Syntax Tree) 抽象语法树!
  • 代码生成
    • 将对应的AST转换为可执行代码的过程!
    • 对应的过程,与语言,目标平台息息相关!

对应的比起编译过程只有三个步骤的语言的编译器而言,JavaScript引擎则复杂得多.

  • 在语法分析和代码生成阶段有特定的步骤对运行性能进行优化! 例如:对冗余元素进行优化!
  • JavaScript引擎不会有大量的时间进行优化,JS与别的语言不同的是,JS编译过程不是发生在构建之前的!
  • 编译发生在JS执行前几微秒,在作用域背后,JS引擎用了九牛二虎之力保证性能,其中包括以下几点:
    • JIT(Just In Time 即时编译)
    • 延迟编译
    • 实施重编译

3.理解作用域

  • 引擎 从头至尾负责JS程序的编译和执行过程
  • 编译器 负责语法分析和代码生成
  • 作用域
    • 收集&维护 查询(由声明的标识符组成!)
    • 一套规则 确定当前执行代码对标识符的访问权限!

首先我们看段代码:

var a = 2;
  • 通过查看这段代码,有几次声明?

    • 编译器编译时的处理
    • 引擎运行代码时处理
  • 编译器是如何处理的呢?

    • 当开始遇到 var a的时候,编译器询问 作用域是否有一个该名称的变量存在于作用域的集合中!
      • 有的话 忽略声明 继续进行编译操作!
      • 否则 在当前作用域中的集合中生命新的变量!
    • 之后为引擎生成运行时所需的代码!
  • 引擎是如何处理的呢?

    • 引擎会询问作用于是否存在对应的变量,如果存在的话,使用该变量,否则继续查找该变量,该变量找不到的话就会报错!
  • 变量赋值操作会执行的两个动作

    • 编译器在当前作用域中声明一个变量(该变量存在的话!)
    • 运行时引擎会在作用域中查找该变量,找到就为其赋值!

4.作用域嵌套

在前面的内容中就已经说到过,作用于其实是一套规则,根据名称查找变量的一套规则,但是实际情况中还是很难避免需要同时估计几个作用域!

当一个块或者函数嵌套在另外一个快或者函数中,就发生了对应的作用于嵌套,因此当我们查找某一个变量的时候无法找到的情况下,引擎就会向外层作用域查找,直到抵达最外层的作用域(全局作用域)为止!

foo(a){console.log(a + b);}
var b = 2;
foo(2);

其实通过这个例子就很明白的知道,在函数 foo中无法找到变量b,但是foo又是存在于全局作用域之下和b在同一个作用于,于是foo作用域找不到的变量在全局作用域中找到了!

遍历作用域链的规则其实很简单,引擎从当前的执行作用域中开始查找该变量,如果找不到的话,就会向上一级查找,直到抵达全局作用域的时候,无论还有没有找到,查找过程都会停止!

对应的我们为了更好的理解作用域的处理过程,嵌套作用域的处理过程向一个链条一样,此时这个链条就叫做作用域链!

如果你有更好的建议或者意见,请在留言区告诉我 _!

相关文章

  • 变量作用域

    变量作用域:静态作用域、动态作用域JS变量作用域:JS使用静态作用域JS没有块级作用域(全局作用域、函数作用域等)...

  • JS作用域的练习

    Js作用域练习demo1 Js作用域练习demo2 JS作用域练习demo3 JS作用域练习demo4 JS作用域...

  • JS

    你不知道的JS 作用域作用域为可访问变量,对象,函数的集合。抛开遮蔽效应,作用域查找始终从运行时所处的最内部作用域...

  • 你不知道的JS-上卷

    作用域整体理解:JS作用域分为函数作用域,全局作用域,with和try catch形成的块级作用域。 JS引擎在编...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

  • 2019-08-13JS里面的作用域Scope

    作用域指一个变量的作用范围。 JS的作用域 在JS中,有两种作用域 全局作用域直接编写在script标签中 JS代...

  • 干货!月薪80k前端大佬面试笔记:JS闭包解析!

    三点注意事项 JS没有块级作用域,只有全局作用域和局部作用域(函数作用域)。 JS中的作用域链,内部的作用域可以访...

  • JavaScript作用域的理解

    作用域:就是起作用的区域。JS的作用域规定了变量和函数可访问的范围。JS作用域分为:全局作用域和局部作用域 全局作...

  • JS 作用域链、导入导出

    1. JS 的作用域链 作用域在 JS 中表示变量的可访问性和可见性。JS 作用域有 3 种:1. 全局作用域;2...

  • JS的作用域

    JS的作用域: 全局作用域、函数作用域、eval 作用域、块级作用域 全局作用域: 函数作用域: 结果截屏: 说...

网友评论

      本文标题:你不知道的JS:作用域是什么?

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