Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >JavaScript中的变量查找

JavaScript中的变量查找

作者头像
娜姐
发布于 2022-05-13 06:28:00
发布于 2022-05-13 06:28:00
1.6K00
代码可运行
举报
文章被收录于专栏:娜姐聊前端娜姐聊前端
运行总次数:0
代码可运行

众所周知,JavaScript变量是按照作用域链来进行查找的(作用域和作用域链相关知识可参看我的另一篇文章,《基于JavaScript作用域链的性能调优》), 那么,对于一个简单的赋值操作,等号左右两边变量的查找方式一样吗?让我们从一个简单例子讲起~

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(a);   // undefined
var a = 3;
console.log(a);   // 3

console.log(b);  // ReferenceError
b = 4;
console.log(b);  //4
1. LHS(left-hand-side左查找)和RHS(right-hand-side右查找)

概念如下:

  • LHS查询:试图找到变量容器本身,从而可以对其进行赋值
  • RHS查询:查找某个变量的值

对于一个赋值语句var a = b;,等号左侧进行LHS查询,等号右侧进行RHS查询;如果是一个普通的打印语句console.log(a),那么,查找变量a属于RHS查询。

两者的相同之处:都遵循作用域链查找

2. LHS和RHS查询区别

(1) LHS查询

当JavaScript引擎执行LHS查询时,如果在顶层作用域中无法找到目标变量,那么,就会在全局作用域中创建一个具有该名称的变量,并将其返回给引擎(非严格模式下)。

要注意,这种方式创建的全局变量,严格上来讲并不是真正的变量,而是全局对象的属性,可以通过delete操作符将其删除。但是,用var声明的全局变量,是不可以用delete操作符删除的。

参考文章首部的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
b = 4;
console.log(b);  // 4
delete b;
console.log(window.b); // undefined

程序中并没有声明变量b,但是由于LHS查询会自动创建未找到的目标变量,所以,打印b返回4。然后删除b,可删除成功。

如果是严格模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";
b = 4;
console.log(b);  

这时LHS查询将无法自动创建未声明的目标变量,所以,打印b时抛出异常:Uncaught ReferenceError: b is not defined

(2) RHS查询

当JavaScript引擎执行RHS查询时,如果在作用域链中都无法找到目标变量,那么,引擎会抛出ReferenceError异常。

参考文章首部的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(b);  
b = 4;

RHS查询变量b,在全局作用域中未曾找到该变量定义,于是,引擎抛出异常Uncaught ReferenceError: b is not defined

3. 小贴士

(1) 变量提升

概念:用var声明的变量,总是会被JavaScript解释器悄悄地“提升”到方法体的最顶部。

参考文首的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(a); 
var a = 3;

JavaScript引擎会将其解析为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = undefined;
console.log(a); 
a = 3;

所以,第一次打印a时会返回undefined

(2) ReferenceError和TypeError

ReferenceError代表作用域判别失败,也就是作用域内查询变量失败。

TypeError代表作用域判别成功,但是对结果的操作是非法或者不合理的。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
foo();
var foo = function () {
     console.log('a');
}

执行foo()语句时,首先RHS查找,在全局作用域中找到foo变量,值为undefined(变量提升)。

然后以函数执行方式操作foo变量,很明显,undefined并不是一个合法函数,于是引擎抛出异常:Uncaught TypeError: foo is not a function,执行失败。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JavaScript词法作用域(你不知道的JavaScript)
1. JavaScript引擎在代码执行前会对其进行编译,在这个过程中,像var a = 2 这样的声明会被分解成两个独立的步骤: 第一步(编译阶段):var a 在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。 第二步(运行阶段):a = 2 会查询变量a(LHS查询)并对其进行赋值。 2. LHS & RHS(当前作用域->上级作用域->...->全局作用域) LHS(左侧):试图找到变量的容器本身 RHS(右侧):查找某个变量的值 示例:
奋飛
2019/08/15
5450
由 JavaScript 的 with 引发的探索
1. 背景 某天吃饭的时候突然想到,都说 with 会有问题,那么是什么问题,是怎样导致的呢?知其然不知其所以然,在好奇心的驱使下,从 with 出发,一路追溯到 VO、AO。那么先来复习一下 with 是干嘛的吧。 2. with js 的 with 是为对象访问提供命名空间式的访问方式,with 创建一个对象的命名空间,在这个命名空间内你可以直接访问对象的属性,而不需要通过对象来访问: const o = { a: 1, b: 2 }; with (o) { console.log(a); /
用户1097444
2022/06/29
3190
由 JavaScript 的 with 引发的探索
JavaScript 实践+理论(总结篇):作用域、闭包、this、对象原型
2. 箭头函数不会使用上述四条规则,而是根据当前的词法作用域来决定 this 的,箭头函数会继承外层函数的 this。
沉浸式趣谈
2024/03/13
1100
JavaScript 实践+理论(总结篇):作用域、闭包、this、对象原型
javascript作用域
javascript的作用域一直以来是前端开发中比较难理解的知识点,对于javascript的作用域主要记住几句话.
Wyc
2018/09/11
4340
javascript作用域
作用域
几乎所有编程语言最基本的功能之一,就是能够存储变量当中的值,并且能在之后对这个值进行访问或修改。那么变量存储在哪里,程序需要时怎么去找到它们?一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则就被称为作用域
Karl Du
2020/10/23
8890
推翻JavaScript中的三座大山:作用域篇
javascript是一门很有意思的编程语言,融合了很多编程语言的特点。上手特别容易,使用javascript开发项目也是很轻松的一件事。但是当你深入其中,你会遇到很多不太好理解的概念,比如闭包、this指向引用、原型链之类。这些模糊的概念,隐藏着javascript微妙之处;真正搞懂这些知识,对于理解javascript之门语言有很大的帮助。本文不讲javascript如何使用,主要是关于javascript中一些难点的分析和理解。
疯狂的技术宅
2019/03/28
5560
JavaScript提升(你不知道的JavaScript)
最近,在读《你不知道的JavaScript(上卷)》这本书,书中详细阐述了JavaScript众多重要但经常被大家忽略的点,在此强烈推荐!!!书中,第4章讲述了“提升”,从示例出发讲述了变量和函数提升的过程,纠正了自己以前错误的理解(相信好多人理解都是错误)! 我们习惯将var a = 2;看做一个声明,而实际上JavaScript引擎不这么认为!下面几个示例让你彻底搞懂JavaScript中的变量提升! 示例1:
奋飛
2019/08/15
3350
深入理解JavaScript作用域
在上一篇文章 深入理解JavaScript 执行上下文 中提到 只有理解了执行上下文,才能更好地理解 JavaScript 语言本身,比如变量提升,作用域,闭包等,本篇文章就来说一下 JavaScript 的作用域。
木子星兮
2020/07/27
7150
深入理解JavaScript作用域
带你了解 JavaScript 作用域
现代编程语言的最基本功能之一就是能够存储变量当中的值,以便于之后的使用于修改。也正是这个功能将状态带给了程序。
大发明家
2021/12/18
3020
JS入门难点解析3-作用域
(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)
love丁酥酥
2018/08/27
5760
读书笔记-你不知道的JavaScript(上)
本文首发在我的个人博客:http://muyunyun.cn/ 《你不知道的JavaScript》系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精华的知识点进行了梳理。 什么是作用域 作用域是一套规则,用于确定在何处以及如何查找变量。 编译原理 JavaScript是一门编译语言。在传统编译语言的流程中,程序中一段源代码在执行之前会经历三个步骤,统称为“编译”。 分词/词法分析 将字符串分解成有意义的代码块,代码块又称词法单元。比如程序var a = 2;
牧云云
2018/05/02
1K0
JavaScript作用域深度剖析:从局部到全局一网打尽
沉浸式趣谈
2024/03/13
1030
JavaScript作用域深度剖析:从局部到全局一网打尽
JavaScript 作用域不完全指北
对于几乎所有编程语言,最基本的功能之一就是能够存储变量的值,并且能在之后对这个值进行访问和修改。这样就会带来几个问题,这些变量存储在哪里?程序在需要的时候又是如何找到它们的?要解决这些问题,就需要引入一套规则来存储变量和访问变量,这套规则就是作用域。
撸码那些事
2019/07/30
3910
《你不知道的JavaScript(上)之作用域》读书笔记
程序设计的概念:一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
after the rain
2022/08/08
5160
深入理解Javacript从作用域作用域链开始
作用域是你的代码在运行时,某些特定部分中的变量,函数和对象的可访问性。换句话说,作用域决定了变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
coder_koala
2019/07/30
5340
深入理解Javacript从作用域作用域链开始
JavaScript执行机制:变量提升、作用域链、词法作用域、块级作用域、闭包和this
所以,JavaScript是ArkTS的基础,本文就来介绍一下JavaScript执行机制的一些核心概念。
陆业聪
2024/07/23
1640
JavaScript执行机制:变量提升、作用域链、词法作用域、块级作用域、闭包和this
关于 JS 闭包看这一篇就够了
LHS (Left-hand Side) 和 RHS (Right-hand Side) ,是在代码执行阶段 JS 引擎操作变量的两种方式,字面理解就是当变量出现在赋值操作左侧时进行LHS查询,出现在右侧时进行RHS查询。更准确的来说,LHS是为了找到变量的容器本身从而可以进行赋值,而RHS则是获取某个变量的值。
用户8921923
2022/10/24
4440
ES6--变量的声明及解构赋值
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
奋飛
2019/08/15
9310
JavaScript 面试要点:作用域和闭包
在当前的作用域中找不到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到 或 到达最外层作用域(全局作用域)为止。
Cellinlab
2023/05/17
4580
JavaScript 面试要点:作用域和闭包
JS学习系列 01 - 编译原理和作用域
在学习 javascript 的过程中,我们第一步最应该了解和掌握的就是作用域,与之相关还有程序是怎么编译的,变量是怎么查找的,js 引擎是什么,引擎和作用域的关系又是什么,这些是 javascript 这门语言最基础的地基,至于对象、函数、闭包、原型链、作用域链以及设计模式等等都是地基以上的建筑,只有地基打牢了,建筑才会稳。同样只有先把最基础的部分掌握了,之后的扩展学习才会更容易。
leocoder
2019/07/09
8790
相关推荐
JavaScript词法作用域(你不知道的JavaScript)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档