基本概念
基本概念
JavaScript 是属于 HTML 和 Web 的编程语言
数据类型
数据类型
- 对象
- 数组
- 函数
- ……
- 基础类型
- 字符串
- 数字
- null
- undefined
- symbol
- bigint
- 布尔
作用域
变量的可访问性和可见性
静态作用域,通过其可以预测代码在执行过程中如何查找标识符
- 全局作用域
- 函数作用域
- 块级作用域
变量提升
如何执行
当JS引擎解析到可执行代码片段的时候,会先做一些执行前的准备工作,这个准备工作叫做执行上下文,也叫执行环境
- 全局执行上下文:是默认的、最基础的执行上下文,程序执行就存在的; 不在任何函数中的代码都位于全局执行上下文中。一个程序中只能存在一个全局执行上下文。它做了两件事: 创建一个全局对象,在浏览器中这个全局对象就是 window 对象 将 this 指向这个全局对象,也就是说在全局执行上下文中 this 指向的是 window
- 函数执行上下文:每次调用函数(包括多次调用同一个函数)时,都会为该函数创建一个新的执行上下文。每个函数都拥有自己的执行上下文,但是只有在函数被调用时才会被创建。一个程序中可以存在任意数量的函数执行上下文
词法环境:词法环境是一种包含标识符=> 变量隐射关系的结构。在词法环境中有两个组成部分:
- 环境记录(EnvironmentRecord):储存变量和函数声明的实际位置,对外部环境的引用。
- 对外部环境的引用(Outer):当前可以访问的外部词法环境。
词法环境分为两种类型:
- 全局环境(Global Environment):全局执行上下文,他没有外部环境的引用,拥有一个全局对象 window 和关联的方法和属性。
- 用户定义的全局变量,并将 this 指向全局对象。
变量环境:变量环境是在声明变量时使用的环境。当声明变量时,JavaScript 引擎会在当前作用域内查找是否有与之匹配的词法环境。如果没有,则在全局环境中查找。如果也没有,则在环境中的默认引用处查找。如果也没有,则返回全局环境。
词法环境用于声明局部变量,而变量环境用于声明全局变量。在 JavaScript 中,变量的作用域和生命周期与其在代码中的位置有关。当在函数内部声明变量时,它们被认为是局部变量,仅在该函数内部可见。当在函数外部声明变量时,它们被认为是全局变量,可以在程序的任何位置使用
进阶
闭包
闭包(closure)是指函数能够访问其自身作用域以及其外部作用域的变量和函数,即使外部函数已经返回,这些变量和函数仍然可以被内部函数访问和操作。
特点:内部函数可以访问外部函数作用域中的变量,而这些变量的值不会在外部函数返回后被销毁。因此,使用闭包可以实现数据的封装和隐藏,使得函数内部的数据可以被长期保留和复用。
this
垃圾回收
JavaScript 垃圾回收是一种自动管理内存使用的机制,用于在程序运行时释放不再使用的内存。在 JavaScript 中,垃圾回收主要包括两个阶段:标记-清除(Mark and Sweep)和分代收集(Generational Collection)。
-
标记-清除(Mark and Sweep):
标记-清除是 JavaScript 垃圾回收的核心机制。在这个阶段,JavaScript 引擎会遍历程序中的所有对象,将不再使用的对象标记为垃圾,然后清除它们。标记-清除阶段的主要任务包括:- 创建垃圾对象的标记。垃圾对象的标记通常是一个布尔值,表示对象是否被引用。当一个对象被标记为垃圾时,JavaScript 引擎会将其标记为 null。
- 遍历对象并清除不再使用的对象。在标记-清除阶段,JavaScript 引擎会遍历程序中的所有对象,将不再使用的对象标记为垃圾,并将其从内存中清除。
-
分代收集(Generational Collection):
分代收集是 JavaScript 垃圾回收的另一种机制。它采用“标记-整理-清除”(Mark and Sweep)的策略,将对象分为不同的年代,每个年代都有自己的垃圾回收策略。在这个阶段,JavaScript 引擎会根据对象的年代和垃圾回收策略来决定如何处理不再使用的对象。分代收集阶段的主要任务包括:- 确定垃圾对象的年代。JavaScript 引擎会根据对象的引用关系和垃圾回收策略来确定垃圾对象的年代。
- 垃圾回收不同年代的对象。在分代收集阶段,JavaScript 引擎会对不同年代的对象采取不同的垃圾回收策略。
- 清除不再使用的对象。在分代收集阶段,JavaScript 引擎会清除不再使用的对象。
事件循环
JavaScript 事件循环是一种处理事件的方式,它可以让你在事件发生时执行一系列的代码。事件循环通常用于处理用户交互,例如在按钮被点击时执行某些操作。
事件循环的基本结构如下:
- 定义一个事件处理函数,该函数将在事件发生时被调用。
- 在事件处理函数中,可以使用
addEventListener方法来监听事件。 - 在事件处理函数中,可以使用
dispatchEvent方法来触发事件。