首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >作用域

作用域

作者头像
Karl Du
发布2020-10-23 17:20:10
8430
发布2020-10-23 17:20:10
举报
文章被收录于专栏:Web开发之路Web开发之路

作用域是什么

几乎所有编程语言最基本的功能之一,就是能够存储变量当中的值,并且能在之后对这个值进行访问或修改。那么变量存储在哪里,程序需要时怎么去找到它们?一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则就被称为作用域

JavaScript是编译型还是解释型语言

JavaScript 是解释型语言。

解释型语言易于实现和理解,及时反馈,但是它运行程序非常慢。编译型在程序运行前就编译好了,而解释型语言是代码运行时去翻译,所以性能不如编译型语言。JavaScript引擎不会有大量时间来进行优化,因为于其他语言不同,JavaScript的编译过程不是发生在构建之前,而是代码执行前的几微秒的时间内。JavaScript用尽各种办法来保证最佳性能,2009 年 Google在 V8 里引入了JIT(Just in time compiling)即时编译技术,瞬间提升了20-4 0倍性能。

编译

1、分词 / 词法分析

将一行行代码分解成有意义的代码块,这些代码块被称为词法单元。例如var a = 2,分解为var、a、=、2

2、解析 / 语法分析

将词法单元流转换成一个由元素逐渐嵌套所组成代表了程序语法结构的树,这个树被称为“抽象语法树”(Abstract Syntax TreeAST

3、代码生成

AST转换为可执行代码的过程被称为代码生成

简单来说就是有某种方法可以将var a = 2AST转换称为一组机器指令,用来创建一个叫作a的变量(包括分配内存),并将一个值存储在a

理解作用域

var a = 2这段程序,引擎会认为是两个不同的声明,一个编译器在编译时处理,另一个则由引擎在运行时处理

我们会这样理解:JS引擎为一个变量分配内存空间,将其命名为a,然后将值 2 保存进这个变量

1、遇到var a,编译器会询问作用域是否已存在该名称的变量并存在同一个作用域集合中。如果是,编译器会忽略该声明,继续编译;否则会要求作用域在当前作用域的集合中声明一个新的变量并命名为a

2、编译器会为引擎生成运行时需要的代码,处理a = 2这个赋值操作。引擎运行时会问该作用域,在当前的作用域集合中是否存在一个叫作a的变量,如果是,引擎就会使用这个变量,如果否,引擎继续查找该变量

function foo() {
  var a = 1;
  var a = 2;
  console.log(a);
}

LHS和RHS

LHS 查询:变量出现在赋值操作左侧

对变量进行赋值(常见的是函数定义,函数传参,变量赋值)

RHS 查询:变量出现在赋值操作非左侧

获取变量的值(常见的是函数调用)

console.log(a) // 此处对 a 的引用就是一个 RHS 引用
a = 2 // 此处对 a 的引用就是一个 LHS 引用

哪里用了 LHS 查询?哪里用了 RHS 查询

function foo(a) {
  console.log(a);
}
foo(2);

作用域嵌套

作用域是根据名称查找变量的一套规则,实际情况中,通常需要同时顾及几个作用域

当一个块或函数嵌套在另一个块中或函数中,就发生了作用域的嵌套。

当在当前作用域没有找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到,或抵达最外层的作用域(全局作用域)

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

这里对b进行的RHS引用无法在函数foo内完成,但可以在上一级作用域完成。

异常

为什么区分LHSRHS是一件很重要的事情

因为在变量还没有声明(在任何作用域都无法找到该变量)的情况下,这两种查询的行为是不一样的。

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

这里对b进行的RHS引用时无法找到该变量的,RHS遇到未声明的变量,引擎就会抛出ReferenceError异常

相较之下,当引擎执行LHS查询,如果在顶层作用域中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,将其返回给引擎,前提是程序运行在非严格模式下,否则也是抛出ReferenceError

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020/9/27 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 作用域是什么
  • JavaScript是编译型还是解释型语言
  • 编译
  • 理解作用域
  • LHS和RHS
  • 作用域嵌套
  • 异常
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档