什么是作用域 对于几乎所有编程语言,最基本的功能之一就是能够存储变量的值,并且能在之后对这个值进行访问和修改。这样就会带来几个问题,这些变量存储在哪里?程序在需要的时候又是如何找到它们的?...引擎运行时会首先询问作用域, 在当前的作用域集合中是否存在一个叫作 a 的变量。 如果是, 引擎就会使用这个变量; 如果否, 引擎会继续查找该变量。...作用域嵌套 我们知道引擎查找变量的过程在作用域中进行的,而这个过程通常会涉及多个作用域。 当一个块或函数嵌套在另一个块或函数中时, 就发生了作用域的嵌套。...因为在变量还没有声明(在任何作用域中都无法找到该变量) 的情况下, LHS 和 RHS两种查询的行为是不一样的。...console.log(a); //ReferenceError: a is not defined 2 2.当引擎执行 LHS 查询时, 如果在顶层(全局作用域) 中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量
引擎运行时会首先询问作用域,在当前的作用域集合中是否存在一个叫作 a 的变量。如果是,引擎就会使用这个变量;如果否,引擎会继续查找该变量。 如果引擎最终找到了 a 变量,就会将 2 赋值给它。...因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量, 或抵达最外层的作用域(也就是全局作用域)为止。...但是如果对变量的查询如果是以查找不到的结果终止时,LHS和RHS的表现是不同的。 如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError 异常。...当引擎执行 LHS 查询时,如果在顶层(全局作用域)中也无法找到目标变量, 全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非 “严格模式”下。...在 严格模式中 LHS 查询失败时,并不会创建并返回一个全局变量,引擎会抛出同 RHS 查询 失败时类似的 ReferenceError 异常。
#什么是## 作用域的概念 现代编程语言的最基本功能之一就是能够存储变量当中的值,以便于之后的使用于修改。也正是这个功能将状态带给了程序。...在JavaScript中,作用域就是一套设计良好的规则来存储变量。 简述编译原理 通常我们会将JavaScript归类为“动态”或“解释执行“语言,但它实际上是一门编译语言。...引擎、编译器、作用域在赋值操作中的配合 引擎:从头到尾负责整个JavaScript程序编译及执行过程undefined 编译器:负责语法分析及代码生成undefined 作用域:负责收集维护由所有变量组成的一系列查询...当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此在当前作用域中没有查找到目标变量时,会逐层向上查找直到全局作用域。...如果LHS查询在所有嵌套的作用域中都没有找到所需变量,引擎就会在全局作用域中创建一个具有该名称的变量,并将其返回给引擎。
简单来说,就是通过某种方法可以将 var a = 5; 的 AST 转化为一组机器指令,用来创建一个叫做 a 的变量(包括分配内存等),并将一个值 5 存储在 a 中。...引擎运行时会首先询问作用域,在当前作用域的集合中是否存在一个叫作 a 的变量,如果是,引擎就会使用这个变量。...如果否,引擎会继续向父级作用域中查找,直到找到全局作用域,如果在全局作用域中仍没有找到 a ,那么在非严格模式下,引擎会为全局对象新建一个属性 a ,并将其赋值为5,在严格模式下,引擎会报错误 ReferenceError...LHS 和 RHS 前面说到引擎在为变量赋值的时候会在作用域中查找变量,但是执行怎样的查找,用什么方式,会对最终的查找结果造成影响。...在 var a = 5; 这个例子中,引擎会对 a 进行 LHS 查询,当然,另外一个查找类型叫作 RHS。 对变量进行赋值所执行的查询叫 LHS。 找到并使用变量值所执行的查询叫 RHS。
当对一个变量执行LHS查询时,同样在遍历作用域后无法找到该变量,在非ES5的严格模式下,系统就会自动在全局作用域中创建一个同名变量,并将引用转移到该新建的全局变量中。...,中luckyGirl在赋值操作的左边,需要为该变量在内存中进行储值,即对luckyGirl进行LHS操作 RHS girlFriend = people ,中people在赋值操作的右边,javascript...('naug'),中together('naug')在赋值操作的右边因此需要知道该函数执行之后的值 小结:如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果目的是获取变量的值,就会使用RHS查询...区分 LHS 和 RHS 的重要性 因为在变量还没有声明(在任何作用域中都无法找到该变量)情况下,这两种查询行为是不一样的。...不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)。
数据存储B. 页面布局C. 服务器端逻辑D. 用户认证JavaScript中,let 和 const 关键字用于声明什么?A. 函数B. 变量C. 对象D. 数组下列哪个不是合法的HTML标签?A....Inner, Outer, Top, Bottom在JavaScript中,parseInt("123px")的结果是什么?A. 123B. "123px"C....大量使用同步加载D. 缓存机制在响应式Web设计中,媒体查询(Media Query)的作用是什么?A. 控制打印样式B. 根据设备特性应用不同的样式C. 提高页面加载速度D....在编程中,用于存储数据的临时存储单元叫做__________。SQL中用于选择所有列的通配符是__________。操作系统的核心功能之一是__________管理。...电子邮件协议中,发送邮件的协议是SMTP(Simple Mail Transfer Protocol)。在编程中,用于存储数据的临时存储单元叫做变量。SQL中用于选择所有列的通配符是 *。
Axel Rauschmayer 在这篇博客中,我们会探究JavaScript全局变量的运行机制。其中,有些有趣的现象将会起到关键作用,如作用域范围、全局对象等等。...某个作用域 S 的最近包含范围称为 S 的外部作用域。在上述示例中,if 的外部作用域就是函数 func。 2 词法环境 在JavaScript语言规范中,作用域是通过词法环境实现的。...其由两个部分组成: Environment Record,环境记录标记了变量名所对应的变量值,例如字典Map,这是Javascript存储变量的地方。...在全局环境的情况下,这个对象就是全局对象 ? 数据结构 接下来将说明如何将对象记录和声明记录组合在一起。...全局对象的存在通常被认为是一个错误,因此,新的语法规范中(如const、let和class)可以创建普通的全局变量(在脚本作用域中)。
众所周知,JavaScript变量是按照作用域链来进行查找的(作用域和作用域链相关知识可参看我的另一篇文章,《基于JavaScript作用域链的性能调优》), 那么,对于一个简单的赋值操作,等号左右两边变量的查找方式一样吗...LHS和RHS查询区别 (1) LHS查询 当JavaScript引擎执行LHS查询时,如果在顶层作用域中无法找到目标变量,那么,就会在全局作用域中创建一个具有该名称的变量,并将其返回给引擎(非严格模式下...参考文章首部的例子: console.log(b); b = 4; RHS查询变量b,在全局作用域中未曾找到该变量定义,于是,引擎抛出异常Uncaught ReferenceError: b is...TypeError代表作用域判别成功,但是对结果的操作是非法或者不合理的。...例如: foo(); var foo = function () { console.log('a'); } 执行foo()语句时,首先RHS查找,在全局作用域中找到foo变量,值为undefined
我们可能多次引用的一条信息可以存储在一个变量中,供以后使用或修改。在JavaScript中,变量中包含的值可以是任何JavaScript数据类型,包括数字、字符串或对象。...变量也可以重新分配,并给定一个新值。下面的简化示例演示了如何将密码存储到变量中,然后进行更新。...//初始化一个全局变量 var creature = "wolf"; 我们知道变量可以重新分配。使用局部作用域,我们实际上可以创建与外部作用域中的变量同名的新变量,而无需更改或重新分配原始值。...在这个例子的结果中,全局变量和块范围的变量都以相同的值结束。这是因为您不是使用var创建一个新的本地变量,而是在相同的范围内重新分配相同的变量。var不能识别是否属于不同的新范围。...//在全局范围内初始化x let x = true;function hoist() { //在函数作用域中初始化x if (3 === 4) { let x = false; }
当一段程序被编译器编译完生成可执行代码,然后引擎执行它时,会对其中的变量进行查询,这个查询过程在作用域协助下,会从当前作用域开始,冒泡向上查找,找到即停止;如果没有找到,会一层层的嵌套进行,直到全局作用域为止...这个过程中变量查询主要分为:LHS查询(赋值操作的目标)或RHS查询(复制操作的源头);如果全局作用域中也没找到,会根据查询类型不同抛出不同错误。...LHS查询在严格模式下抛出ReferenceError,非严格模式下隐式的创建全局变量;RHS抛出ReferenceError错误。 词法作用域 javascript中的绝大部分作用域都是词法作用。...【函数作用域】 函数作用域中属于这个函数的全部变量都可以在整个函数范围内使用及复用。...这里我们使用了闭包+块代码,其中块代码的作用域是全局的,所以当执行完循环之后运行setTimeout中闭包之后,其中引用的i就是全局公共区域中的i,也就是6。所以最终输出6个6.
• 因为在变量还未声明(在任何作用域中都无法找到该变量)的情况下,引擎的这两种查询行为是不一样的。...进行 LHS 查询时,如果在顶层(全局作用域)中也没找到该变量,就会在全局作用域中隐式地创建一个该名称的变量,并将其返回给引擎。 3. ...... • 严格模式下: 1....因此在严格模式中引擎执行 LHS 查询失败时,并不会创建一个全局变量,而是直接抛出一个 ReferenceError。 2....引擎常使用的查询类型为:LHS 和 RHS • = 操作符在调用函数时的形参会导致关联作用的赋值操作。...因此在严格模式中引擎执行 LHS 查询失败时,并不会创建一个全局变量,而是直接抛出一个 ReferenceError。 2.
引擎执行 LHS 查询时如果找不到该变量,则会在全局作用域中创建一个。...如果查找的目的是对变量进行赋值,那么就会使用 LHS查询; 如果目的是获取变量的值,就会使用 RHS 查询;JavaScript 引擎执行代码前会对其进行编译,这个过程中,像 var a = 2 这样的声明会被分解成两个独立的步骤...全局作用域和函数作用域 全局作用域 在最外层函数和最外层函数外面定义的变量拥有全局作用域 var a = 1; function foo() { } 变量a 和函数声明 foo 都是在全局作用域中的...我们在 for 循环的头部直接定义了变量 i,通常是因为只想在 for 循环内部的上下文中使用 i,但是实际上 此时的 i 被绑定在外部作用域(函数或全局)中。...const也是可以用来创建块级作用域变量,但是创建的是固定值。 作用域链 JavaScript是基于词法作用域的语言,通过变量定义的位置就能知道变量的作用域。全局变量在程序中始终都有定义的。
在谈论 JavaScript 中的垃圾收集时,几乎不可能不触及「可达性」的概念。 3.1 可达性 在特定作用域中的所有值或在作用域中使用的所有值都被称为在该作用域中的“可达”,并被称为“可达值”。...可访问的值总是存储在内存中。 在以下情况下,值被认为是可达的: 程序根中的值或从根中引用的值,如全局变量或当前执行的函数、它的上下文和回调。...通过引用或引用链从根中访问的值(例如,全局变量中的对象引用另一个对象,该对象也引用另一个对象——这些都被认为是可访问的值)。...可以缓存函数的结果,以便在调用函数时重用缓存的结果。 让我们来看看实际情况。...副作用是,每当对象不需要时,我们就需要清理 cachedResult。使用 WeakMap(),一旦对象被垃圾回收,缓存的结果就会自动从内存中删除。
JavaScript中的作用域 在 JavaScript 中有两种作用域 全局作用域 局部作用域 如果一个变量在函数外面或者大括号{}外声明,那么就定义了一个全局作用域,在ES6之前局部作用域只包含了函数作用域...最常见的就是函数作用域。 2.2.1 函数作用域 定义在函数中的变量就在函数作用域中。并且函数在每次调用时都有一个不同的作用域。这意味着同名变量可以用在不同的函数中。...就像代码中的例子,一个只在for循环内部使用的变量i不会再去污染整个作用域。...而这一条形成的“AO链” 就是JavaScript中的作用域链。 3.3 找过程LHS和RHS查询特殊说明 LHS,RHS 这两个术语就是出现在引擎对变量进行查询的时候。...Learning Javascript, LHS RHS 3.3.1 LHS和RHS特性 都会在所有作用域中查询 严格模式下,找不到所需的变量时,引擎都会抛出ReferenceError异常。
3.14159; // 使用const定义常量 JavaScript变量的命名规则 在JavaScript中,变量的命名必须遵循一些规则: 变量名必须以字母、下划线(_)或美元符号($)开头。...const uniqueID = Symbol("id"); 在JavaScript中,变量的数据类型是动态的,这意味着可以在不同时间存储不同类型的值在同一个变量中。...在JavaScript中,有两种主要类型的作用域:全局作用域和局部作用域。 全局作用域:在全局作用域中声明的变量可以在代码的任何地方访问。全局作用域通常包含整个JavaScript程序。...当变量在内部作用域中使用时,JavaScript会首先查找该变量是否在内部作用域中声明,如果没有,则会逐级向外查找,直到找到该变量或达到全局作用域。这就是所谓的作用域链。...避免全局变量:尽量减少全局变量的使用,因为它们容易导致命名冲突和不可预测的行为。 块级作用域:在ES6之后,块级作用域已经变得更容易使用。
一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则就被称为作用域 JavaScript是编译型还是解释型语言 JavaScript 是解释型语言。...(包括分配内存),并将一个值存储在a中 理解作用域 var a = 2这段程序,引擎会认为是两个不同的声明,一个编译器在编译时处理,另一个则由引擎在运行时处理 我们会这样理解:JS引擎为一个变量分配内存空间...引擎运行时会问该作用域,在当前的作用域集合中是否存在一个叫作a的变量,如果是,引擎就会使用这个变量,如果否,引擎继续查找该变量 function foo() { var a = 1; var a...当在当前作用域没有找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到,或抵达最外层的作用域(全局作用域) function foo(a) { console.log(a + b); }...异常 相较之下,当引擎执行LHS查询,如果在顶层作用域中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,将其返回给引擎,前提是程序运行在非严格模式下,否则也是抛出ReferenceError
都是分别定义在全局作用域中的函数,它们是并列的,所以在 foo1 的作用域链中并不包含 foo2 的作用域,虽然在 foo2 中调用了 foo1,但是 foo1 对变量 a 进行 RHS 查询时,在自己的作用域没有找到...,引擎会去 foo1 的上级作用域(也就是全局作用域)中查找,而并不会去 foo2 的作用域中查找,最终在全局作用域中找到 a 的值为 2。...因为 eval("var a = 10;") 在 foo 的作用域中新创建了一个同名变量 a,引擎在 foo 作用域中对 a 进行 RHS 查询,找到了新定义的 a,值为 10,所以不再向上查找全局作用域中的...复制代码 如上所示,我们对 c 进行 LHS 查询,因为在 with 引入的新作用域中没有找到 c,所以向上一级作用域(这里是全局作用域)查找,也没有找到,在非严格模式下,在全局对象中新建了一个属性...,就会进入 catch 块,此时会把异常对象添加到作用域链的最前端,类似于 with 一样,catch 中定义的局部变量也都会添加到包含 try...catch 的函数作用域(或全局作用域)中。
1.4 异常 1)如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常; 2)非“严格模式”下当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量...,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎; 3)“严格模式”下如果LHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎也会抛出ReferenceError异常; 4)ReferenceError...1.5 小结 1)作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。 2)如果查找的目的是对变量进行赋值,那么就会使用LHS查询,如果目的是获取变量的值,就会使用RHS查询。...函数作用域和块作用域 3.1 函数作用域 函数作用域的含义是指属于这个函数的全部变量都可以在整个函数的范围内使用及复用(在嵌套的作用域中也可以使用)。...2)模块管理 另外一种避免冲突的办法和现代的模块机制很接近,就是从众多模块管理器中挑选一个来使用,使用这些工具,任何库都无需将标识符加入到全局作用域中,而是通过依赖管理器的机制将库的标识符显示地导入到另外一个特定的作用域中
LHS和RHS查询都会在当前执行作用域中开始,如果它们没有找到所对应的标识符,就会沿作用域向外层作用域查找,直到抵达全局作用域再停止。 不成功的RHs引用会导致抛出ReferenceError。...对b进行RHS引用,在func函数内部作用域中无法找到,但可以在上级作用域(全局作用域)中找到,而c在整个作用域链中都没有找到,所以抛出了ReferenceError异常。...由于原生Javascript不支持模块化,在正式的模块化方案出来之前,开发者为了解决这类问题想到了使用函数作用域来创建模块的方法。...a ,由于函数作用域的隔离性质,这两个变量被保存在不同的作用域中(不嵌套),JS 引擎在执行这两个函数时会去不同的作用域中读取,并且外部作用域无法访问到函数内部的 a 变量。...也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
词法作用域 在深入学习闭包之前,我们需要了解与闭包相关的基本知识,词法作用域。 JS的作用域的概念:引擎用来管理当前作用域和嵌套的子作用域中根据标识符名称进行变量查找的一套规则。...关联到全局作用域 以值的形式返回内部标识符getName的函数,赋值给变量nameFun 执行nameFun,查询执行标识符getName,实际上调用的是内部函数getName getName被执行,...,执行到closureFun函数作用域,查询到变量name,打印执行结果。...我们也可以这样理解闭包:访问并记住词法作用域的函数叫闭包。 闭包的应用 在前端开发过程中,我们经常使用的闭包应用包括:匿名立即执行函数,存储变量,封装私有变量。...变量存储和管理 在我们开发过程中,我们可以使用闭包的特性创建常量: const person = () => { let name= "javaScript" return () =>
领取专属 10元无门槛券
手把手带您无忧上云