读书笔记《你不知道的JavaScript上卷》1.1作用域是什么

ArcGIS实战:地形湿度指数(TWI)计算全流程解析 本文详细解析了ArcGIS中地形湿度指数(TWI)的计算全流程,从DEM数据获取、填洼处理到水流方向与汇流累积量计算,最终实现TWI的精准计算。通过实战步骤指导,帮助读者掌握水文建模和土壤湿度预测的关键技术,适用于农业规划、生态研究等领域。 阅读详情

作用域是什么

JavaScript是一门非常神奇的编程语言,以至于你没有掌握它的精髓都可以写出完整的项目,本套读书笔记记录的就是《你不知道的JavaScript上卷》中的内容,其中会夹杂这我个人对某些知识点的感悟与见解。


1.1 编译器与引擎

在讨论作用域是什么的时候不得不讲讲另外两个概念,一个是编译器另一个是引擎。

  • 编译器 负责语法分析及代码生成等工作
  • 引擎 负责整个JavaScript程序的编译及执行的过程

看了这两个概念后相信大家跟我一样也是一头雾水,这两个东西到底是干什么的?简单的讲就是对于一行代码:

var a = 2;

这行代码在解析与执行的时候并不是按一次来处理,而是分两次来处理。

  • 首先,编译器会判断当前作用域中有没有声明过该变量,如果声明过了则忽略该语句,如果没有生成过则声明该变量
  • 其次,在运行的时候引擎会在作用域中查找该变量,如果找到了就赋值

所以上述代码可以看成是两行代码:

var a;//这部分由编译器来处理,先声明一个变量
a=2;//这部分由引擎来处理,给变量赋值

通常情况下我们程序猿不需要知道什么是编译器什么是引擎,用一个高大上的词来说就是他们对我们来说是透明的,但是我们一定要知道在处理声明和赋值的时候是分为两个过程,这在就是JavaScript中变量提升(后续笔记中会讲到)的原因。

1.2 作用域

上一小节谈到了是JavaScript声明和赋值是两个过程,本章节就是围绕这两个过程来展开,首先让我们谈谈什么是作用域。

作用域: 通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。 —— [ 百度百科 ]

简单的说作用域就是变量的有效范围。JavaScript最常见的作用域就是函数作用域。就比如:

function foo(){
    var a = 3;
}
console.log(a);//这里找不到变量a因为它在自己的作用域中,即函数foo所形成的作用域

变量a所在函数foo的作用域中,而外面打印a的时候,在他所处的作用域中并没有a这么一个变量,所以会报ReferenceError这样的错误。

1.3 作用域链

在JavaScript中有两大链是我们必须要掌握的,其中一个就是作用域链,另一个就是原型链。我们这里首先讲的是作用域链,它是一个非常重要的概念。

作用域链:引擎从当前的执行作用域开始查找变量,如果找不到,就向上一级继续查找,再找不到就继续向上一级中找,直到找到该变量或者到达最外层的作用域(即全局作用域)。

这句话,什么意思呢?上代码:

var a = 3;
function bar(){
    var a = 2;//如果这一行注释掉那么将会打印3
    function foo(){
        console.log(a);//打印2    
    }
    foo();
}
bar();

在讲这段代码之前大家首先要知道JavaScript中函数是可以嵌套的,像上面的bar函数中嵌套了一个foo的函数一样,这一点不同于Java等某些编程语言。
上述代码调用了bar函数,该函数内部又会调用函数foo,而foo内部打印了a变量,但是函数foo内部(即函数foo作用域中)并没有声明过a这个变量,那么它会去上一作用域中查找这个变量,即他外层的函数bar的函数作用域,这个作用域中有a的声明,并且值是2,那么foo函数打印的值就是2了。如果bar中的语句”var a = 2;”是不存在的那么在bar作用域中还是没有找到,那么它就会继续去上一作用域也就是最外层的全局作用域中查找,则会找到a=3,那么这种情况下将会打印3了。

1.4 异常

相信上小节讨论作用域链的时候很多人会问那如果到了最外层的全局作用域还没有找到那么会发生什么事。本节就讨论一下这种情况。

如果查询完所有嵌套的作用域中都没有找到所需要的变量的声明和赋值语句,引擎就会抛出出ReferenceError。

什么意思呢?如下:

function bar(){
    function foo(){
        console.log(a);//没有找到a,抛出ReferenceError 
    }
    foo();
}
bar();

上述代码中没有找到a这个变量的声明和赋值语句就会抛出ReferenceError。

如果查询完所有嵌套的作用域中找到了所需要的变量赋值语句但没有声明语句,全局作用域就会创建一个该变量,并返回给引擎。

这句话又是什么意思呢?如下:

function bar(){
    a = 1;//找到赋值了 但全局都没有声明,所以最外层的全局作用域会创建一个该变量,故打印1
    function foo(){
        console.log(a);//有a的赋值返回1
    }
    foo();
}
bar();

上述代码中没有找到a这个变量赋值语句了,但没有声明所以最外层的全局作用域会“友好“地创建一个该变量a,故打印1。
但是有赋值语句这种情况还有另外一种情况。
在ES5中引入了一种严格模式,顾名思义严格模式是因为它对语法的检查更为严格,这种模式下禁止自动或隐式地创建全局变量。对于这种情况, 如果查询完所有嵌套的作用域中只要没有找到所需要变量的声明语句无论是否找到赋值语句,引擎都会抛出ReferenceError。我们给上面代码加上严格模式后效果如下:

"use strict";//有了这行神奇的代码编译器就知道你使用的是严格模式了
function bar(){
    a = 1;//找遍所有的作用域都没有找到a的声明语句,只有赋值语句
    function foo(){
        console.log(a);//同样抛出ReferenceError
    }
    foo();
}
bar();

说到这里这节的笔记就接近尾声了,最后简绍一下另外一个与ReferenceError同样高频的一个错误叫做TypeError。

TypeError: 当给一个变量做违反该类型的操作时就会抛出该异常。

这个异常太常见了就比如给一个非函数类型的值进行函数调用,或者调用undefined的某个属性呀(umdefined没有object类型中的属性)等等都会发生这个异常,如下,代码都会报TypeError错误:

var a = 1;
a();//a是number类型的不能进行函数引用
var b
console.log(b.name);//b没有赋值,是undefined类型,该类型没有name这么个属性
保姆级教程:在Ubuntu 20.04上搞定pybind11,解决‘找不到头文件’的坑 本文提供了一份详细的Ubuntu 20.04下pybind11配置指南,重点解决常见的'找不到头文件'问题。从环境准备、安装策略到三种专业解决方案(修改CMakeLists.txt、环境变量方案、绝对路径包含),帮助开发者高效搭建C++与Python的桥梁。 阅读详情

相关推荐

使用python排八字 计算八字的相合相冲五行分值等 ...

简介 八字术是一种古老的算命术。它运用阴阳、五行、干支、八卦等理论,把人的出生年月日时转化为八个字,进而推算人的富贵贫贱、祸福吉凶、穷通寿天、名利地位、家庭六亲等方面的情况 八字源自古代的中国,是一种利用天干和地支来准确记录年、月、日、时的方式,由“年干,年支”、“月干,月支”、“日干,日支”、“时干,时支”,共八个干支所组成(共八个字),年、月、日、时...

weixin_33717298的博客 5310

《你不知道的JavaScript》笔记(一)

用了一个星期把《你不知道的JavaScript》看完了,但是留下了很多疑惑,于是又带着这些疑惑回头看JavaScript的内容,略有所获。 第二遍阅读这本书,希望自己能够有更为深刻的理解。 词法作用域 ……如果是 有状态 的解析过程,还会赋予单词语义…… 这本书是以编译原理的部份内容结合JavaScript来开篇的,所以如果没有学过编译原理,这一小部分内容显得有些晦涩。 虽然多数人没有...

专注前端领域方向的内容 365

基于OpenAI Agents构建多智能体工作流:从原理到实战

多智能体系统(Multi-Agent System)是人工智能领域的重要分支,它通过多个智能体(Agent)的协作与交互,解决单一智能体难以处理的复杂任务。其核心原理在于将任务分解、分配与协调,每个智能体具备特定能力,通过通信机制实现信息共享与决策协同。在工程实践中,多智能体框架的价值在于提升任务处理效率、增强系统鲁棒性,并支持模块化开发。典型的应用场景包括自动化工作流编排、复杂问题求解以及人机协同交互。本文以OpenAI Agents SDK为例,深入探讨如何利用其提供的智能体(Agent)、会话(Ses

weixin_28725959的博客 606

你不知道的JS(上卷)——读书笔记1 作用域是什么

第一章 作用域 根据名称来查找变量的一套规则 编译 传统编译:代码在执行前会经历三个步骤,统称为编译 分词/词法分析:把代码分为代码块(词法单元) 解析/语法分析:把词法单元(数组)转换成由元素嵌套组成的代表了程序语法的树(抽象语法树AST) 代码生成:根据AST生成可执行的代码 JS编译:JS的编译过程还包括了性能优化等操作。JS的编译过程发生在代码执行之前,编译后基本上代码立即执行 编译过程的参与者: 引擎:负责整个JS程序的编译和执行过程 编译器:负责语法分析及代码生成 作用域:负责收集和维护所

weixin_44710964的博客 220

Python 打包与发布陷阱:如何用 setuptools 和 PyInstaller 生成跨平台可执行文件?

使用。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1209

Rocky Linux 9 离线环境Docker部署全攻略:从依赖打包到服务启动

本文详细介绍了在Rocky Linux 9纯离线环境中部署Docker的完整流程。从在联网环境精准下载Docker静态二进制包及所有系统依赖RPM包,到在隔离服务器上按顺序安装依赖、部署二进制文件、配置systemd服务并进行权限与网络调优,提供了从零到一的可复现实战指南。文章重点解决了离线部署的核心难题,并分享了搭建私有镜像仓库等进阶技巧,是运维人员在严格网络管控环境下部署容器服务的必备参考。

pytorchlight8的博客 138

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.4

函数作用域和块作用域 作用域包含了一些“容器”,其中包含了标识符(变量,函数)的定义,这些容器互相嵌套并整齐排列成蜂窝状,排列的结构是在写代码时定义的。 但是,究竟是什么生成了一个新的容器?只有函数可以吗?JavaScript中的其它结构能生成容器吗? 对于此问题,最常见的答案是JavaScript具有基于函数的作用域,意味着每声明一个函数都会为其自身创建一个容器,而其它结构都不会创建作用域...

qq_34241037的博客 299

手把手教你用FPGA驱动DAC8830:一个Verilog SPI驱动模块的完整实现与调试

本文详细介绍了如何使用FPGA通过Verilog实现DAC8830的SPI驱动模块,包括SPI通信机制解析、Verilog模块设计、代码优化及调试技巧。重点解决时钟同步、状态机设计等工程实践问题,适用于音频处理、仪器仪表等高精度数模转换场景。

weixin_26886855的博客 230

读书笔记《你不知道的JavaScript上卷》1.2词法作用域

词法作用域就是定义在词法阶段的作用域,它由写代码时将变量和块作用域写在哪里来决定的。

逝水流光的博客 689

排查单片机不工作的‘玄学’故障:从LDO选型、复位电路到焊接不良的完整避坑指南

本文深入剖析单片机不工作的常见硬件故障,从LDO选型、复位电路设计到PCB布局和焊接工艺,提供系统性排查方法。重点分析3.3V电源稳定性、LDO动态响应特性及复位电路设计要点,帮助工程师快速定位和解决嵌入式系统中的'玄学'故障,提升产品可靠性。

weixin_30655569的博客 389

YOLOv8【第十二章:数据增强与数据工程篇·第10节】主动学习(Active Learning):如何挑选最有价值的样本进行标注!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏。该专栏系统复现并梳理全网各类 YOLOv8 改进与实战案例(当前已覆盖分类 / 检测 / 分割 / 追踪 / 关键点 / OBB 检测等方向),坚持持续更新 + 深度解析,质量分长期稳定在 97 分以上,可视为当前市面上 覆盖较全、更新较快、实战导向极强 的 YOLO 改进系列内容之一。

**My Coding Family** 509

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.5

提升 函数作用域和块作用域的行为是一样的,可以总结为:任何声明在某个作用域内的变量,都将附属于这个作用域。 但是,作用域同其中的变量声明出现的位置有某种微秒的联系。 “先有鸡还是现有蛋” 直觉上认为,js代码在执行时是由上到下一行一行执行的,但是实际上并不完全正确。典型代码如下所示: a=2; var a; console.log(a);//2 这段代码的运行...

qq_34241037的博客 203

ESP32设备驱动-MLX90393磁场传感器驱动

MLX90393 磁场传感器可以在运行时重新编程为不同的模式和不同的设置。 该传感器使用 Melexis 专有的 Triaxis® 技术提供与沿 XYZ 轴感应的磁通密度成比例的 16 位输出,还提供温度输出信号。 这些数字值可通过 I2C 和 SPI 获得,其中 MLX90393 是总线上的从设备。

视觉与物联智能 2356

读书笔记《你不知道的JavaScript上卷》1.5作用域闭包

闭包:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。 这是闭包的定义,对于一个作用域(就比如函数所形成的作用域)来说,通常情况下,当执行完这个函数以后,JS引擎的垃圾回收机制就可能会回收掉这个函数所占用的内存,但是如果这个函数形成了闭包那么它就不会回收掉这个函数所占用的内存了。

逝水流光的博客 457

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.1

0.作用域是什么? 1.存储和访问变量的值的能力将状态带给了程序。 2.需要一套设计良好的规则来存储变量,并且之后可以方便的找到这些变量,这套规则称为作用域。 最初个人的理解作用域是“势力范围”,看来还是粗浅了一些,对“势力范围”进行抽象即变量存储和访问的规则。 1.编译原理 1.尽管通常将JavaScript归类为“动态”或者“解释执行”的语言,但事实上它是一门编译语言。但是与传统的编...

qq_34241037的博客 230

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.3

词法作用域 作用域共有两种主要的工作模型。第一种是最为普遍的,被大多数编程语言所采用的词法作用域,另一种叫作动态作用域,仍有一些编程语言在使用(比如 bash,perl中的一些模式等)。 大部分标准语言编译器的第一个工作阶段叫词法化(也叫单词化)。 简单的说,词法作用域就是定义在词法阶段的作用域,换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时...

qq_34241037的博客 222

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.2

理解作用域 承上文,目前出现了三个概念: 1.引擎:从头到尾负责整个JavaScript程序的编译及执行过程 个人感觉就像CPU里面的控制单元 2.编译器:引擎的好朋友之一,负责语法分析以及代码生成等脏话类活 个人感觉就像CPU里面的ALU 3.作用域:引擎的好朋友之一,负责收集维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访...

qq_34241037的博客 226

读书笔记《你不知道的JavaScript上卷》1.3函数作用域和块作用域

函数作用域和块作用域 函数作用域:属于这个函数的全部变量都可以在整个函数的范围内访问(事实上在嵌套的作用域中也可以访问)。 3.1 函数中的作用域函数可以形成作用域,这个大家都知道的,如下代码:function foo() { var a = 2; console.log("函数foo中的a:" + a);//打印 函数foo中的a:2 } foo(); console.log(

逝水流光的博客 364

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.6->闭包->No.2

看一段代码: var a=2; (function IIFE(){ console.log(a); })(); 虽然这段代码可以正常工作,但是它严格来讲并不是闭包。 因为函数IIFE并不是在它本身的词法作用域以外执行的。它在定义时所在的作用域中执行,实际效果与下段代码相同: function IIFE2(){ console.log(a); }; IIFE2(); a是通过普通的词法...

qq_34241037的博客 231

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.6->闭包->No.0

启示 对于那些有一点js使用经验但从未真正理解闭包概念的人说,理解闭包可以看做是某种意义上的重生。 js中闭包无处不在,闭包并不是一个需要学习新的语法或模式才能使用的工具。 闭包是基于词法作用域书写的代码时所产生的自然结果。 实质定义:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。 我们来看一段代码,清晰的展示了闭包: function f...

qq_34241037的博客 181

《你不知道的JavaScript》(上卷)读书笔记:作用域和闭包1.6->闭包->No.1

无论使用何种方式,对函数类型的值进行传递,当函数在别处调用时都可以观察到闭包。 在js里面,函数可以像其他类型一样,作为函数的参数进行传递! 我们类比一下C语言,实现类似的功能依赖的是函数指针,在js中,我们虽然传递的是函数名,但实质应该也是指向函数体所在起始位置的指针(猜测js引擎会有一个map以存储变量名和其首地址)。 我们看一下下面的代码的执行过程: 我们看一下执行栈,foo调用...

qq_34241037的博客 171

《你不知道的JavaScript上卷》知识点整理与读书笔记

第一部分 作用域和闭包 第1章 作用域是什么 1.1编译原理 1.2理解作用域 1.3作用域嵌套 1.5异常 第2章 词法作用域 第3章 函数作用域和块作用域 第5章 作用域和闭包 第二部分 this和对象原型 第1章 关于this 第2章 this全面解析 第3章 对象 第4章 混合对象“类” 第5章 原型 第6章 行为委托 之前被好友推荐过《你不知道的JavaScript》这一系列的书籍。上中下三本书都不算厚,内容也是比较独立。本来是打算一个月内看完这本上卷和下卷,可总是因为自己的.

qq_45549336的博客 6405

你不知道的JavaScript 上卷读书笔记

看了《你不知道的JavaScript 上》,为了防止自己忘记,特此记下与我而言的部分重点 任何足够先进的技术都和魔法无异。 ——Arthur C. Clarke 作用域和闭包 编译原理 分词/词法分析(Tokenizing/Lexing) 编程语言的所有字块与符号都会被分解为词法单元; var a = 2; //分解为var、a、=、2、;。 // ! 空格是否被当做词法单元,取决于空格在这门语言中是否具有意义 解析/语法分析(Parsing) 这个过程是将词法单元流转换成一个由元素逐.

weixin_42832836的博客 679

《你不知道的javascript(上卷)》——读书笔记

《你不知道的javascript(上卷)》 摘要:         我觉得这本数对javascript的一些难点有深层次的分析,遂打算近日拿来学习.          本书目录:                 第一部分: 作用域和闭包                第二部分: this和对象原型 第一部分: 作用域 概念:引

weixin_40821790的博客 1044

你不知道的JavaScript(上卷)读书笔记

《你不知道的JavaScript(上卷)》读书笔记。

多啦的博客 865

《你不知道的JavaScript上卷》知识点整理与读书笔记_百度你不知道的js书知识

/也就是这个对象本身,想一想为什么this是指向这个对象本身,我保证前面的this里面讲的知识,绝对可以分析出来这里的this指向哪里。foo.call(obj)//2 这里显示调用,foo中this是obj,所以回调中是obj的a。//这行代码只是为了验证()中的var i,以及{}中的a,最后在外部均可以访问到这两个标识符。foo()//3 这里光秃秃调用,foo中this是window,所以回调中是window的a。//当然把最后的()放进去的效果也是一样的,仅仅是书写风格不同。

m0_61067876的博客 1146
上一篇: SWT自动补全
下一篇: 读书笔记《你不知道的JavaScript上卷》1.2词法作用域
javao_0
博客等级 码龄12年 6粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值