JS —— 数组和对象
本文按照 Mozilla 贡献者基于 CC-BY-SA 2.5 协议发布的以下文章改编:
- https://developer.mozilla.org/zh-CN/docs/Learn/JS/First_steps/Arrays
- https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/Basics
我们上次讲了变量。这是一种用来存单个值的容器。但是如果我们要存多个值呢?比如我们现在需要统计一个班级的人名,或者统计每天的气温,这显然就不能用反复声明大量的变量进行存储。所以我们就要引出本章的主角:数组和对象。
数组
数组是一系列按顺序排列的值的集合。它可以一下子存下一系列的值,就相当于一些按顺序排列的变量。比如我们现在要去超市买东西,依次买了很多物品,并且记录了它们的价格。
数组包裹在一对中括号内 ( []
) ,里面的值按顺序排列,并且使用英文逗号进行分隔 ( ,
) 。可以通过在数组名后面加上一个 ( []
) ,然后在括号内使用通过从零开始的下标来找到对应的值。下面我们给出了一系列的例子。
1 | > let shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles']; |
数组里的值甚至可以是另一个数组,这叫做数组嵌套,下面演示了嵌套数组的行为。
1 | > let random = ['tree', 795, [0, 1, 2]]; // 声明一个嵌套的数组 |
数组方法
length
最常用的数组方法,可能就是获取数组长度了。数组长度可以通过 length
方法来获取,就是在数组名之后加上一个 .length
,例如 sequence.length
就可以了解我们下面定义的数组的长度。
1 | > let sequence = [1, 1, 2, 3, 5, 8, 13]; // 声明一个数组 |
length 属性最常用的时候,就是循环遍历一个数组中的所有项目。比如说下面的这个代码:
1 | let sequence = [1, 1, 2, 3, 5, 8, 13]; |
我们以后会详细了解循环,但是这里先稍微提下这里主要干的事情:
- 在数组中的元素编号 0 开始循环。
- 在元素编号等于数组长度的时候停止循环。 这适用于任何长度的数组,但在这种情况下,它将在编号 7 的时候终止循环(还记得数组的编号是从 0 开始的吗?0 到 6 就是 7)。
- 对于每个元素,使用 console.log() 将其打印到浏览器控制台。
字符串和数组之间的转换
有时候你会需要把一个有规律的字符串转化成数组来处理数据,比方说这样的字符串
1 | let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle'; |
显然,这里是用 ,
来分割的一系列单词。如果我们要把它转成一个数组,就可以用 split()
方法,它会对字符串进行处理,然后返回一个数组。方法的用法是在字符串之后加上一个 .split()
,在括号内指定分隔符(默认是空格)。
1 | > let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle'; |
如果要把数组转成对应的字符串,可以用相反的方法 .join()
,用法和前面的相同。(假设我们这里是紧跟着上面执行的)
1 | > let myNewString = myArray.join(','); |
添加和删除数组项
这里我们可以使用 push()
和 pop()
方法在数组尾部进行添加和删除元素。使用 push()
方法之后会返回新数组的长度,使用 pop()
方法之后会返回被删除的那个值。也许你可以用变量存下它们。
1 | > let myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle']; |
采取这个方法我们可以模拟一个栈操作。栈是一种 LIFO(先进先出)的数据结构。通俗的讲起来就像是叠盘子,后面的叠在上面,拿的时候就拿走最上面的。最后叠的最先拿出来,就是一个先进先出了。以后我们会单独开章节讲数据结构,当作拓展的内容。
对象
我们刚刚提到了数组,这是一种按顺序存值的方法。它用途非常广泛,但是因为只能按下标找值,在有些时候可能会比较难用。比如现在我们要存一个人的相关信息,比如名字,性别,年龄,简介这些,如果用数组就会遇到一个难题:必须给这些信息确定一个顺序,规定第一个是名字,第二个是性别等等。这样写会带来理解上面的困难(一堆乱七八糟的数字可不是很好阅读的)。如果使用一系列的单一变量去存,会搞出一大堆变量。那么有没有更好的方法呢?答案是使用对象。
对象 (Object) 是包含一系列相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)。由于我们目前还没有讲函数,我们暂时先讲对象的数值相关的东西,以后在函数部分再提对象的方法。
对象使用一对大括号 ( {}
) 来表示,里面包含着很多用逗号分开的成员,每一个成员都拥有一个名字(下面的 name, age 这些),和一个值(如[“Linus”, “Torvalds”], 52 都是值)。每一个名字和值(Name and Value)之间由冒号(:)分隔,然后就可以通过成员的名字来查找对应的值。下面是一个例子。为了看得更清楚,我们在其中插入了换行,一行一个成员。我们推荐在以后编程实践当中适当使用换行,因为可以让代码更加整洁。
1 | let person = { |
可以使用点表示法来查找对应的值,就是在对象标识符之后加上一个点,在点后面加上键名称就可以了,比如 person.age
就可以对应 person
的 age
对应的值,即 52
。
还有另一种表示法是括号表示法,用法类似数组,是在一个中括号 []
内加上键名称来对应的,例如 person["saying"]
就可以对应到那个 saying
。
我们建议使用点表示法,因为更加简洁,方便打字。
下面是在 NodeJS 里面运行的结果,换行之后那三个点是 node 加上的,表示上一句话还没结束。这不是代码的一部分,所以自己写代码的时候不要加上去。
1 | > let person = { |
子命名空间
可以用一个对象来做另一个对象成员的值。比如我们现在可以把 person
的 name
从一个数组换成一个对象。就像是下面这样。
1 | let person = { |
这样就可以用点表示法进行多重的查找,比如 person.name.firstName
这样子
1 | > let person = { |
这样非常有用,因为你可以在对象里面嵌套另一个对象,从而有结构地保存一系列的数据,起到方便阅读和维护的作用。
设置对象成员
有时候我们需要对对象进行一系列的操作。比方说我们可能会修改一个成员,可能会加上一个还没有的成员,或者一个成员不要了我们可以删除它。这些都是可以做到的。
现在我们再创建一次上文中的 person
对象,然后对这个变量进行一系列操作:
1 | let person = { |
现在你可以试着修改其中的成员:
1 | > person.name = 'Tux'; // 设置名字 |
你可以删除其中的成员
1 | > delete person.saying; |
还可以直接添加原来没有的成员
1 | > person.newValue = 123; |
方法
其实对象远远比我们现在讲的要复杂多了,比如对象的成员可以不只是一个普通的值,还可以是函数(事实上这个才是对象里面用的最多的)。关于函数的定义比较复杂,现在你可以认为是一组执行任务或计算值的语句。在对象里面作为的函数叫做这个对象的方法。
下面我们看下这个例子,我们给它添加了一个用来在控制台进行输出的方法。
1 | person.say = function (){ |
在 NodeJS 中运行。
1 | > person.say = function (){ |
可以看到我们让 person
对象输出了自己的名字。简单地说我们干了这几件事情:
- 使用 function 关键字表明下面是一个函数
- 在函数里定义了一条
console.log()
语句,向控制台输出。 - 用 this 定位到自己本身,然后把自己的名字拼接到字符串内
- 使用
person.say()
来进行输出。
所以我们之前遇到的很多东西 (例如本章讲的 push()
pop()
或者刚刚用到的 console.log()
) 其实都是方法。有关于函数的内容我们会在以后详细地了解。
小结
我们了解了数组和对象。
数组是一种按顺序保存一系列值的数据结构,声明的时候用一对的中括号 []
来表示,其中可以包含用逗号分隔的值。
数组的每个元素可以采用下标进行查找,下标范围从 0 开始到比长度小一的值结束,你可以用 length
来获取长度。
数组和字符串之间可以使用 split()
和 join()
方法进行相互转换。
可以用 push()
在数组末尾加入值,也可以用 pop()
来删除末尾的值。
对象通过一对大括号 {}
来声明,里面用逗号分隔每一个成员。成员是由 名字: 值
的配对组成的。
对象的成员可以用点表示法查找,也可以使用括号表示法。
对象的成员就像一个普通的变量,可以进行修改。如果给一个原本没有的成员进行赋值,会添加一个新的成员。
对象的成员可以是函数,这也叫做方法。
练习
罗辑经常会忘记自己在谈的对象的名字,因此要你去用对象去记录她们的信息。现在他给你了一些信息,要你马上拿一个对象存起来。记住,只能用一个对象存。(名字都是书里抄的)
要求声明一个 girls
对象,将变量存到同名的成员内,然后使用 console.log()
输出对象。
1 | let name1 = "张珊" |
下面是一个数组,你需要把其中的第二项和第四项交换,然后输出数组。(注意下标从零开始)
1 | let myArray = [ 1, 4, 3, 2, 5, 6, 7]; |