"精讲.md"
### 变量的理解
在编程语言中,变量扮演着至关重要的角色。变量是一个容器,用于存储数据,就像一个杯子可以装不同类型的液体。因此,变量能够存储不同类型的数据,这些数据根据特性被分为不同的数据类型。
JavaScript 中,数据类型主要分为两大类:基本数据类型(简单类型)和引用数据类型(复杂类型)。基本数据类型包括六种原始类型:Number、Boolean、String、Undefined、Null 和 Symbol,ES2020 引入了BigInt,用来存储大整数。而引用数据类型则有 Object、Function、Array、Date、RegExp 等,它们在内存中以对象的形式存在。
变量中存储的数据是可变的,我们可以通过赋值操作来改变变量的值。要检测变量的数据类型,可以使用 `typeof` 操作符,但要注意它对于某些引用类型(如数组和函数)可能会返回 'object'。`instanceof` 则用于判断一个实例是否属于某个构造函数的类型。
在存储机制上,基本数据类型存储在栈内存中,而引用数据类型的对象存储在堆内存中,栈中仅保存对象的引用(地址)。因此,当两个变量都指向同一个堆内存中的对象时,它们之间进行的实际上是引用传递,而不仅仅是值的复制。而基本数据类型之间则是值传递,因为它们直接存储的是值,而非引用。
变量还分为局部变量和全局变量。局部变量在函数内部声明,作用域仅限于该函数,函数执行完毕后,它们会被自动释放或销毁。全局变量在整个脚本或页面范围内都是可访问的,其生命周期贯穿整个程序运行期间。
### 执行上下文
执行上下文是 JavaScript 解释代码时的环境,分为全局执行上下文和函数执行上下文。预解析是 JavaScript 的一个特性,它发生在代码真正执行之前。在预解析阶段,变量和函数会被声明,但不会立即赋值或执行。这个过程包括变量声明的提升(Hoisting)和函数表达式的提升,但 ES6 中的 `let` 和 `const` 声明不再被提升。
全局执行上下文可以看作是一个全局对象,其中包含了所有的全局变量和函数。当进入一个函数执行上下文时,会创建一个新的作用域链,这个链指向当前执行上下文的变量对象和其父级(全局上下文)的变量对象,以便于访问不同层次的作用域内的变量。
在预解析过程中,变量和函数被声明,但赋值操作会在实际执行时进行。例如,如果你预先声明了一个变量并尝试在声明之前使用它,JavaScript 不会抛出错误,而是使用 `undefined`。函数表达式也会在这个阶段被解析,但它们不会被执行,直到被调用。
理解变量、数据类型、执行上下文以及预解析是深入学习 JavaScript 的基础,这有助于编写更高效且无错的代码。在编写程序时,合理利用这些概念可以避免许多常见的问题,并提高代码的可读性和可维护性。