日期:2022年10月3日

字面量和变量

字面量

字面量其实就是一个值。像1、2、3这种数字,又像是”abc”、”你好”、”锄禾日当午”这种字符串,再有就是true、false这些布尔值,都是字面量。所谓的字面量,指这些值所代表的意思就是它们字面上的含义,1就是1、2就是2、”hello”就是”hello”,没有其他特殊含义。

在JS中字面量都是可以直接使用的:

<script>
    console.log(123)
    console.log("hello")
    console.log(true)
    console.log(null)
</script>

字面量虽然可以直接使用,但若真的使用会带来诸多的不便:

  1. 字面量只有字面意思,只使用字面量无法判断其含义。比如,数字10,如果只看到一个10我们没有办法判断它所代表的含义。10岁?10千克?10米?无法得知。
  2. 字面量无法修改。字面量一旦使用便无法更改,这导致使用字面量后要想修改必须使用新的字面量去替换原来的,十分不便。

变量

变量可以用来“存储”字面量,这里存储加了引号,后边的课程我们会解释。变量的作用类似于数学中的变量(未知数)。在数学中我们可以这样,设小明的身高为x,设了x后便可以用x代表小明的身高。同理在编程语言中,我们可以用变量来存储一个字面量,这样就可以使用变量来代表这个字面量了。

<script>
    let a = 10
    let b = "hello"
    let c = true
</script>

相较于字面量,变量有很多的优势:

  1. 变量可以自己命名,可以通过变量来描述字面量。比如,可以使用age = 10,这样我们通过变量的名字就能判断10是年龄而不是其他。
  2. 变量可以修改。使用变量时,如果想修改变量的值,直接重新对其赋值即可,无需其他多余操作。

所以在开发中,我们应该尽量多地使用变量,而减少直接使用字面量。

变量的使用

声明变量

要使用一个变量必须先对变量进行声明,JS是一门动态类型的语言,变量时没有类型的。但由于历史原因,变量的声明有两种方式,旧版本的var和新版本的let:

<script>
    let a
    var b
</script>

在实际使用中还是推荐使用新版本的let,而不要用var。它们的具体区别我们会在后边的课程中学习。

为变量赋值

声明变量后,可以直接使用=来为变量赋值,赋值后可以任意的修改变量的值,JS中没有任何的限制。

<script>
    let a
    a = 10
    a = 20
    a = 'hello'
</script>

同时声明和赋值

更常见的用法是,声明和赋值同时进行。

<script>
    let a = 10
</script>

常量

除了变量外,在JS中还可以使用const关键字来声明常量,区别于变量,常量只能在初始化时对其赋值,一旦赋值则无法修改。

<script>
    const a = 20
    a = 30 // 报错 Uncaught TypeError: Assignment to constant variable.
</script>

在JS中除了一些常规的常量外,还经常使用const声明用来存储对象的变量,这样可以避免变量被意外修改。

标识符

JS中所有的可以自主命名的内容都可以认为是标识符。像是:变量、函数名、类名等。标识符虽然由我们自主命名,但是命名时还需要遵循一些规则:

  1. 标识符只能含有字母、数字、_和$,且不能以数字开头。
  2. 标识符不能是JS中的关键字和保留字。列表
  3. 标识符需要使用固定的命名方式:
    1. 常规,驼峰命名法:首字母小写,单词开头大写。例如:maxlength -> maxLength
    2. 类名,大驼峰命名法:首字母大写,单词开头大写。例如:maxlength -> MaxLength
    3. 常量,全都使用大写,字母使用_分开。例如:maxlength -> MAX_LENGTH

变量存储的是内存地址

注意:本文中的内存结构都是简化过的内存结构,实际内存结构要更复杂一些

在上文中我们一直反复的说,变量存储字面量,变量存储字面量…… 甚至后边我们依然会反复的说这句话。但是严格来说这句话并不准确,因为变量并不直接存储字面量,而是存储字面量的内存地址。

内存

程序运行中的所有数据都要存储到内存中,JavaScript中使用的变量和字面量也不例外。变量在内存中的结构类似于一个表格,表格中一列是变量的名字,一列是变量的值,像下面的一段代码,在内存中的结构大概是下图的样子:

let a
let b
let c

由于还没有为变量赋值,所以值的位置是空的。假如是这样一段代码呢?

let a = 10
let b = "hello"
let c = true

a、b、c三个变量我们已经知道在哪存储了,那么10、”hello”、true这些字面量要存储在哪呢?最容易想到的是字面量可以存储到变量的第二个列中,像是这样的:

但是很可惜这错误的,因为这种结构JavaScript无法实现或很难实现。为什么呢?首先10、”hello”、true这些字面量,也需要占用内存,并且很明显它们占用内存的大小是不同的。而变量一旦创建其内存大小就已经确定了,那么值那一列要留多大的内存才能存储这些字面量呢?内存留小了,大的字面量放不下。内存留大了,小的字面量用不完,会浪费。并且我们也不可能设置一个固定的空间使其可以容纳任意的字面量,这是做不到的。

实际上,每当我们创建了一个字面量时,JavaScript就会为其在内存中开辟出一块新的空间,专门用来存储这个字面量,这块空间将刚好容纳下该数据。每一个块内存空间都会有一个唯一的内存地址,变量只需存储内存地址,即可和字面量产生关联。例如let a = 10这样一行代码,它的内存结构是这样的:

当我们访问一个变量时,解析器会先找到对应的变量,再通过变量中存储的内存地址找到对应的字面量。

相较于直接存储字面量来说,内存地址的大小是固定的。此时解析器只需为变量分配一个和内存地大小一样的空间,即可确保一个变量可以存储任意类型的值。

5 3 投票数
文章评分
订阅评论
提醒
guest

4 评论
最旧
最新 最多投票
内联反馈
查看所有评论
0mato1
0mato1
2 月 前

老师加油

Nina3375
Nina3375
2 月 前

李老师,变量的使用下面一个小节《声明变量》,您的本意应该是在实际使用中还是推荐使用新版本的let,而不要用var吧,误写成了不要用let 🙂

Nina3375
Nina3375
2 月 前
回复给  李立超

不客气!另外,老师可以写一篇关于JS Web Worker的理解吗?什么时候或场景会使用它?谢谢!

4
0
希望看到您的想法,请您发表评论x