大家好!欢迎来到 JS 脚本语言系列的第二课。今天,我们要一起深入聊聊 JavaScript 中极其核心、也是大家每天都会打交道的一个基础概念——变量。
什么是变量?为了让大家更好理解,我们先从大家熟悉的数学场景切入。如果你学过初中数学,并且接触过一次函数(比如 y = kx + b),那么在老师第一次给你讲解时,一定会提到“变量”这个词。在数学里,变量被定义为“取值不定的量”。它会随着条件的变化而变化,但在变化的过程中,每一个 x 的值都有唯一确定的一个 y 值与其对应。在这里,x 就是变量,而对应关系或某些固定参数就是常量。顾名思义,变量就是“会变的量”,这一点在数学和编程中应该没什么争议。
然而,当语境切换到编程世界时,变量的概念被进一步抽象和扩展了。它不再像数学那样,仅仅局限于表示一个数值,或者每一个变量只能严格对应一种特定类型的值。在 JavaScript 中,变量变得极其灵活,它可以存储各种不同类型的值。例如,当你在 JS 脚本中声明一个变量 `let a;` 时,这个 `a` 接下来可以被赋值为字符串、布尔值,甚至是复杂的函数、对象、数组等等。当你成功完成赋值后,这个变量就真正被激活并声明成功了。
今天的内容,我们主要可以分为三个核心部分来和大家详细聊一聊:一、变量的本质;二、变量名的命名规范;三、变量声明的关键字。
首先,我们来看第一部分:变量的本质。如前文所述,在数学的纯粹世界里,变量往往只和数字打交道,它代表的是一个会变的数值。但在编程语境下,我们更倾向于把变量理解为一个“容器”或者“盒子”。
这个容器非常神奇,它不仅可以装数字,还能装布尔值、字符串、函数、数组、对象以及其他任何你能想到的数据类型。更酷的是,在 JS 这种弱类型(动态类型)语言中,你赋值后的数据类型,完全可以和你最初声明时的类型不同,甚至可以在使用过程中随时改变。
我们以这段代码为例来具象化一下:
let pluginJS = {
name: "abc",
ID: "com.abc.example",
Description: "懒得写",
Author: "Abc",
tags: ["js", "script", "tutorial"]
};
在这个例子中,我们声明了一个变量,变量名是 `pluginJS`,我们将它赋值给了一个对象。这个对象内部包含了 `name`、`ID`、`Author`、`Description` 等基础属性,甚至还包含了一个 `tags` 数组。之后,如果我们想在代码的其他地方引用这个庞大的对象,直接调用变量名 `pluginJS` 即可。如果你只想提取宿主对象中的某一个具体属性,比如想知道作者是谁,你可以使用“变量名.属性名”的方式(即 `pluginJS.Author`)来精准查找并获取当前变量所含对象中的属性值。
所以你看,变量在编程里就完美承担了一个“容器”的角色,你往里面放什么,它就能装什么。它不像数学里的 x 只能代表数字,它可以是任意数据类型。你甚至可以在同一个变量里,先存一个数字,接着把它清空换成一个字符串,最后再塞进去一个函数,这在 JS 里都是完全允许的:
let a = 1; // 此时 a 是数字类型
a = "hello"; // 现在 a 变成了字符串类型
a = function() { // 接着 a 又变成了一个函数
console.log("hi");
当然,在实际的企业级开发中,我们一般强烈不建议你这么“折腾”一个变量。因为频繁改变变量的数据类型,会让代码的逻辑变得难以追踪,极大地增加后续阅读和维护的成本。但至少通过这个小例子你要明白:JS 的变量是动态类型的,它的类型是跟着当前的赋值走的,而不是在声明时就死死绑定的。
接下来,我们聊聊第二部分:变量名。变量名,顾名思义就是你给这个“容器”贴上的标签、起的名字,比如刚才的 `pluginJS`。在 JS 里,变量名可不是你随心所欲、随便乱起的,它有一套严格且优雅的命名规则:
- 字符限制:变量名只能包含字母(a-z, A-Z)、数字(0-9)、下划线 `_` 和美元符号 `$`。并且,绝对不能以数字开头。这是因为解析器需要区分变量名和纯数字字面量。
- 关键字避让:变量名不能是 JS 的保留字或关键字。比如 `let`、`const`、`var`、`if`、`for`、`function`、`return` 这些系统已经占用的词汇,你绝对不能拿来当变量名,否则编译器会直接报错。
- 大小写敏感:JS 是严格区分大小写的语言。这意味着 `name`、`Name` 和 `NAME` 在 JS 眼里是三个完全不同的变量,互不干扰。
- 命名规范:虽然下划线和美元符号可以用,但在实际开发中,我们强烈推荐大家使用驼峰命名法(Camel Case)。也就是第一个单词首字母小写,后续单词首字母大写,比如 `myName`、`userAge`、`pluginData`。这样不仅符合行业规范,读起来也更具语义化,清晰易懂。
比如下面这些变量名都是完全合法且规范的:
let name; // 基础单词
let _temp; // 下划线开头(常用于表示私有或临时变量)
let $el; // 美元符号开头(常用于表示DOM元素或jQuery对象)
let userName; // 标准的驼峰命名
let pluginJS; // 包含大写的驼峰命名
相反,下面这些则是典型的错误示范,是不合法的:
let 1abc; // 错误:以数字开头
let my-name; // 错误:减号(-)不是允许的字符,会被解析为减法运算
let let; // 错误:使用了系统关键字
接下来我们进入第三部分,也是极其重要的一部分:变量关键字。在现代 JavaScript 的语法体系中,声明变量主要依靠三个关键字:`var`、`let` 和 `const`。
首先说说 `var`。`var` 是 ES5 及以前老版本语法体系中使用的变量关键字,它是 variable(变量)的缩写。由于它采用的是“函数作用域”,并且存在“变量提升”的特性,这意味着在整个函数内部,无论你在哪里声明的 `var` 变量,它在函数顶部就已经被感知到了。这种特性在早期经常会引起一些意想不到的逻辑 Bug。
为了彻底解决这些历史遗留痛点,JS 语言的设计者在 ES6 体系中引入了 `let` 关键字。`let` 引入了“块级作用域”的概念,让变量的作用范围更加直观和可控,相当于直观地让一个变量在特定的代码块内等于一个值,这就很好理解了。
那很多同学可能会问:“老师,`const` 难道不也是一个变量关键字吗?”
严格来说,对我而言,`const` 其实不能算作一个完整的、传统意义上的“变量”关键字。为什么这么说呢?因为 `const` 声明的其实是一个“常量”(constant)。它声明以后不能够被无限次重新赋值,也就是“赋值一次即绑定”,后续再尝试修改它的值就会报错。
但是!这里有一个非常重要、且面试常考的细节需要和大家强调一下。虽然 `const` 声明的变量不能重新赋值,但如果它存储的是“引用数据类型”(比如对象 Object 或者数组 Array),我们是完全可以修改其内部的属性或元素的。
这是为什么呢?因为 `const` 保证的,其实并不是“变量的值不得改动”,而是“变量指向的那个内存地址所保存的数据不得改动”。对于基本数据类型(如数字、字符串),值本身就保存在那个内存地址中,所以等同于绝对的常量;但对于引用数据类型,那个内存地址保存的只是一个“指针”(或者说门牌号),`const` 只能保证这个“指针”不变(即不能指向另一个新的对象),而不能保证“指针”所指向的那栋房子里的家具(数据结构)不变。
我们来看个具体的例子,保证你一看就懂:
const user = { name: "Alice" };
user.name = "Bob"; // 这是合法的!我们只是修改了对象内部的属性,指针没变。
// user = { name: "Charlie" }; // 这是非法的!会报错,因为你尝试给 user 重新赋值,改变了它的指针指向。
讲完了这三个关键字的特性,我们来简单总结一下它们在实际开发中的最佳使用建议。在现代 JavaScript 开发规范中,我们通常遵循这样一个黄金原则:优先使用 `const`,只有在明确确定该变量在后续代码中需要被重新赋值时,才退而求其次使用 `let`,而尽量彻底抛弃 `var`。
这样做的好处是显而易见的:一方面可以让代码的意图更加清晰,直接告诉看代码的人“这个值在生命周期内是不会变的”;另一方面,也能从根本上避免很多因为 `var` 的函数作用域和变量提升带来的潜在 Bug,让代码更加健壮。
好了,到这里,我们今天的三个核心部分就全部讲完了。我们来简单回顾一下今天的重点:
首先,我们打破了数学里对变量的固有认知,明白了在 JS 中变量其实是一个可以装任何数据类型的“万能容器”;
其次,我们掌握了变量名的命名规则,知道了怎么给容器起一个合法、规范且见名知意的好名字;
最后,我们详细拆解了 `var`、`let` 和 `const` 这三个关键字的区别、作用域差异以及底层的内存逻辑。
希望大家通过这节课,能够对 JS 中的变量有一个更加清晰、透彻、立体的理解。变量是编程的基石,把这块基础打牢,后面的函数、对象、异步等高级学习才会更轻松。
大家下去以后,可以尝试着动手实践一下:用几个随机的变量名,搭配今天学的固定关键字,声明并赋值几个不同类型的变量。如果没有报错,说明你已经完全掌握了变量的基础知识。如果在练习中遇到了报错,或者对某些概念还有疑惑,欢迎在评论区跟帖回复,我们一起探讨。
在下一节课(第三课)中,我们会接触到如何让代码“说话”——也就是“注释”的艺术。下课
目录
大家好!欢迎来到 JS 脚本语言系列的第二课。今天,我们要一起深入聊聊 JavaScript 中极其核心、也是大家每天都会打交道的一个基础概念——变量。
什么是变量?为了让大家更好理解,我们先从大家熟悉的数学场景切入。如果你学过初中数学,并且接触过一次函数(比如 y = kx + b),那么在老师第一次给你讲解时,一定会提到“变量”这个词。在数学里,变量被定义为“取值不定的量”。它会随着条件的变化而变化,但在变化的过程中,每一个 x 的值都有唯一确定的一个 y 值与其对应。在这里,x 就是变量,而对应关系或某些固定参数就是常量。顾名思义,变量就是“会变的量”,这一点在数学和编程中应该没什么争议。
然而,当语境切换到编程世界时,变量的概念被进一步抽象和扩展了。它不再像数学那样,仅仅局限于表示一个数值,或者每一个变量只能严格对应一种特定类型的值。在 JavaScript 中,变量变得极其灵活,它可以存储各种不同类型的值。例如,当你在 JS 脚本中声明一个变量 `let a;` 时,这个 `a` 接下来可以被赋值为字符串、布尔值,甚至是复杂的函数、对象、数组等等。当你成功完成赋值后,这个变量就真正被激活并声明成功了。
今天的内容,我们主要可以分为三个核心部分来和大家详细聊一聊:一、变量的本质;二、变量名的命名规范;三、变量声明的关键字。
首先,我们来看第一部分:变量的本质。如前文所述,在数学的纯粹世界里,变量往往只和数字打交道,它代表的是一个会变的数值。但在编程语境下,我们更倾向于把变量理解为一个“容器”或者“盒子”。
这个容器非常神奇,它不仅可以装数字,还能装布尔值、字符串、函数、数组、对象以及其他任何你能想到的数据类型。更酷的是,在 JS 这种弱类型(动态类型)语言中,你赋值后的数据类型,完全可以和你最初声明时的类型不同,甚至可以在使用过程中随时改变。
我们以这段代码为例来具象化一下:
let pluginJS = {
name: "abc",
ID: "com.abc.example",
Description: "懒得写",
Author: "Abc",
tags: ["js", "script", "tutorial"]
};
在这个例子中,我们声明了一个变量,变量名是 `pluginJS`,我们将它赋值给了一个对象。这个对象内部包含了 `name`、`ID`、`Author`、`Description` 等基础属性,甚至还包含了一个 `tags` 数组。之后,如果我们想在代码的其他地方引用这个庞大的对象,直接调用变量名 `pluginJS` 即可。如果你只想提取宿主对象中的某一个具体属性,比如想知道作者是谁,你可以使用“变量名.属性名”的方式(即 `pluginJS.Author`)来精准查找并获取当前变量所含对象中的属性值。
所以你看,变量在编程里就完美承担了一个“容器”的角色,你往里面放什么,它就能装什么。它不像数学里的 x 只能代表数字,它可以是任意数据类型。你甚至可以在同一个变量里,先存一个数字,接着把它清空换成一个字符串,最后再塞进去一个函数,这在 JS 里都是完全允许的:
let a = 1; // 此时 a 是数字类型
a = "hello"; // 现在 a 变成了字符串类型
a = function() { // 接着 a 又变成了一个函数
console.log("hi");
};
当然,在实际的企业级开发中,我们一般强烈不建议你这么“折腾”一个变量。因为频繁改变变量的数据类型,会让代码的逻辑变得难以追踪,极大地增加后续阅读和维护的成本。但至少通过这个小例子你要明白:JS 的变量是动态类型的,它的类型是跟着当前的赋值走的,而不是在声明时就死死绑定的。
接下来,我们聊聊第二部分:变量名。变量名,顾名思义就是你给这个“容器”贴上的标签、起的名字,比如刚才的 `pluginJS`。在 JS 里,变量名可不是你随心所欲、随便乱起的,它有一套严格且优雅的命名规则:
- 字符限制:变量名只能包含字母(a-z, A-Z)、数字(0-9)、下划线 `_` 和美元符号 `$`。并且,绝对不能以数字开头。这是因为解析器需要区分变量名和纯数字字面量。
- 关键字避让:变量名不能是 JS 的保留字或关键字。比如 `let`、`const`、`var`、`if`、`for`、`function`、`return` 这些系统已经占用的词汇,你绝对不能拿来当变量名,否则编译器会直接报错。
- 大小写敏感:JS 是严格区分大小写的语言。这意味着 `name`、`Name` 和 `NAME` 在 JS 眼里是三个完全不同的变量,互不干扰。
- 命名规范:虽然下划线和美元符号可以用,但在实际开发中,我们强烈推荐大家使用驼峰命名法(Camel Case)。也就是第一个单词首字母小写,后续单词首字母大写,比如 `myName`、`userAge`、`pluginData`。这样不仅符合行业规范,读起来也更具语义化,清晰易懂。
比如下面这些变量名都是完全合法且规范的:
let name; // 基础单词
let _temp; // 下划线开头(常用于表示私有或临时变量)
let $el; // 美元符号开头(常用于表示DOM元素或jQuery对象)
let userName; // 标准的驼峰命名
let pluginJS; // 包含大写的驼峰命名
相反,下面这些则是典型的错误示范,是不合法的:
let 1abc; // 错误:以数字开头
let my-name; // 错误:减号(-)不是允许的字符,会被解析为减法运算
let let; // 错误:使用了系统关键字
接下来我们进入第三部分,也是极其重要的一部分:变量关键字。在现代 JavaScript 的语法体系中,声明变量主要依靠三个关键字:`var`、`let` 和 `const`。
首先说说 `var`。`var` 是 ES5 及以前老版本语法体系中使用的变量关键字,它是 variable(变量)的缩写。由于它采用的是“函数作用域”,并且存在“变量提升”的特性,这意味着在整个函数内部,无论你在哪里声明的 `var` 变量,它在函数顶部就已经被感知到了。这种特性在早期经常会引起一些意想不到的逻辑 Bug。
为了彻底解决这些历史遗留痛点,JS 语言的设计者在 ES6 体系中引入了 `let` 关键字。`let` 引入了“块级作用域”的概念,让变量的作用范围更加直观和可控,相当于直观地让一个变量在特定的代码块内等于一个值,这就很好理解了。
那很多同学可能会问:“老师,`const` 难道不也是一个变量关键字吗?”
严格来说,对我而言,`const` 其实不能算作一个完整的、传统意义上的“变量”关键字。为什么这么说呢?因为 `const` 声明的其实是一个“常量”(constant)。它声明以后不能够被无限次重新赋值,也就是“赋值一次即绑定”,后续再尝试修改它的值就会报错。
但是!这里有一个非常重要、且面试常考的细节需要和大家强调一下。虽然 `const` 声明的变量不能重新赋值,但如果它存储的是“引用数据类型”(比如对象 Object 或者数组 Array),我们是完全可以修改其内部的属性或元素的。
这是为什么呢?因为 `const` 保证的,其实并不是“变量的值不得改动”,而是“变量指向的那个内存地址所保存的数据不得改动”。对于基本数据类型(如数字、字符串),值本身就保存在那个内存地址中,所以等同于绝对的常量;但对于引用数据类型,那个内存地址保存的只是一个“指针”(或者说门牌号),`const` 只能保证这个“指针”不变(即不能指向另一个新的对象),而不能保证“指针”所指向的那栋房子里的家具(数据结构)不变。
我们来看个具体的例子,保证你一看就懂:
const user = { name: "Alice" };
user.name = "Bob"; // 这是合法的!我们只是修改了对象内部的属性,指针没变。
// user = { name: "Charlie" }; // 这是非法的!会报错,因为你尝试给 user 重新赋值,改变了它的指针指向。
讲完了这三个关键字的特性,我们来简单总结一下它们在实际开发中的最佳使用建议。在现代 JavaScript 开发规范中,我们通常遵循这样一个黄金原则:优先使用 `const`,只有在明确确定该变量在后续代码中需要被重新赋值时,才退而求其次使用 `let`,而尽量彻底抛弃 `var`。
这样做的好处是显而易见的:一方面可以让代码的意图更加清晰,直接告诉看代码的人“这个值在生命周期内是不会变的”;另一方面,也能从根本上避免很多因为 `var` 的函数作用域和变量提升带来的潜在 Bug,让代码更加健壮。
好了,到这里,我们今天的三个核心部分就全部讲完了。我们来简单回顾一下今天的重点:
首先,我们打破了数学里对变量的固有认知,明白了在 JS 中变量其实是一个可以装任何数据类型的“万能容器”;
其次,我们掌握了变量名的命名规则,知道了怎么给容器起一个合法、规范且见名知意的好名字;
最后,我们详细拆解了 `var`、`let` 和 `const` 这三个关键字的区别、作用域差异以及底层的内存逻辑。
希望大家通过这节课,能够对 JS 中的变量有一个更加清晰、透彻、立体的理解。变量是编程的基石,把这块基础打牢,后面的函数、对象、异步等高级学习才会更轻松。
大家下去以后,可以尝试着动手实践一下:用几个随机的变量名,搭配今天学的固定关键字,声明并赋值几个不同类型的变量。如果没有报错,说明你已经完全掌握了变量的基础知识。如果在练习中遇到了报错,或者对某些概念还有疑惑,欢迎在评论区跟帖回复,我们一起探讨。
在下一节课(第三课)中,我们会接触到如何让代码“说话”——也就是“注释”的艺术。下课