数组
在看这一部分时,你需要对领域的列表有一定的了解。
JavaScript 中的数组相当于属性中的列表。数组会按顺序存储各类数值。在本文中,“数组”和“列表”表示的概念是相同的。
创建数组
数组由中括号表示,在中括号内,用逗号分隔不同的元素。例如:
[1, 2, 3, 4]
含有 1 2 3 4 四个数字, ['文本1', '文本2', '文本3']
含有 文本 1 文本 2 文本 3 三个文本。创建一个名为“物品列表”的数组:
var 物品列表 = ['剑', '盾', '弓', '箭']
上述代码创建了一个名为“物品列表”的临时变量,包含四个文本:'剑'、'盾'、'弓' 和 '箭'。
获得数组在某个位置的值
通过
数组名称[位置]
提取数组某个位置的值,数组位置从『0』开始,依次递增。访问物品列表中的第一个玩家:
var 物品列表 = ['剑', '盾', '弓', '箭']
var 第一个物品 = 物品列表[0] // 结果是 '剑'
物品列表[0]
指物品列表的第一个值,物品列表[1]
指第二个值,诸如此类。请确保在访问数组的某个值时,不会超出数组的长度,否则会返回 undefined。
修改数组在某个位置的值
通过
数组名称[位置] = 新的值
修改数组在某个位置的值。修改“物品列表”数组中的第二个元素:
var 物品列表 = ['剑', '盾', '弓', '箭']
物品列表[1] = '圆盾' // 将原来的 '盾' 替换为 '圆盾'
获得数组长度
通过
数组名称.length
得到数组含有元素的数量,也就是长度。获得“物品列表”的长度,并赋值给变量“列表长度”:
var 物品列表 = ['剑', '盾', '弓', '箭']
var 列表长度 = 物品列表.length // 结果是 4,因为物品列表有 4 个元素
在数组末尾添加元素
通过
数组名称.push(新的值)
在数组末尾添加新的元素。在物品列表末尾添加“枪”:
var 物品列表 = ['剑', '盾', '弓', '箭']
物品列表.push('枪') // 现在物品列表变成了 ['剑', '盾', '弓', '箭', '枪']
操作列表类型的属性
操作列表类型的属性和临时变量类似。只需要将变量名换成
属性.属性名
,例如:清空一个列表类型的属性:
属性.伙伴列表 = [];
属性.提示文本 = '成功清空了你的所有伙伴。';
[]
代表数组中没有任何值,相当于清空了数组。查找数组中某个值的位置
通过
xxx.indexOf(某值)
查找数组中某个值第一次出现的位置。通过
xxx.lastIndexOf(某值)
查找数组中某个值最后一次出现的位置。如果没有找到值,会返回-1。
var 数组 = ['a', 'b', 'c', 'a', 'b', 'c'];
var 位置 = 数组.indexOf('c'); //返回数字2,代表'c'首次出现的位置
var 位置2 = 数组.lastIndexOf('c'); //返回数字5,代表'c'最后出现的位置
if (位置 === -1) {
属性.提示文本 = '没有找到这个值!';
return;
}
可以结合 push 和 indexOf,实现让玩家加入某个活动,并且只能加入一次。
//假设全局属性『加入成员』的类型是玩家列表,装有加入某个活动的所有成员
//现在,某个玩家想加入活动,则需要从属性『加入成员』中添加该玩家
var 位置 = 属性.加入成员.indexOf(玩家.id); //查找这个玩家在数组中的位置
if (位置 >= 0) {
属性.提示信息 = '你已经加入这个活动了,你是第' + (位置 + 1) + '个加入这个活动的成员。';
return;
}
属性.加入成员.push(玩家.id); //把这个玩家添加到名单末尾
属性.提示信息 = '操作成功!已经把你添加到加入名单中,你是第' + 属性.加入成员.length + '个加入这个活动的成员。';
删除数组中的值
通过
xxx.splice(位置,删除数量)
删除数组中从『位置』开始的值,并返回所有被删除的值(一个数组)。如果『位置』是负数,则从后往前。例如,-1 是数组最后一个值,-2 是数组倒数第二个值。
var 数组 = ['a', 'b', 'c', 'a', 'b', 'c'];
var 删除的值 = 数组.splice(2, 1); //删除数组在位置2的一个值,即'c'
// 数组:['a', 'b', 'a', 'b', 'c'] (操作后,数组少了'c')
// 删除的值:['c']
可以结合 indexOf 和 splice,实现删除数组中特定的值。
//假设全局属性『加入成员』的类型是玩家列表,装有加入某个活动的所有成员
//现在,某个玩家想退出活动,则需要从属性『加入成员』中删除该玩家
var 位置 = 属性.加入成员.indexOf(玩家.id);
if (位置 === -1) {
属性.提示信息 = 'Oops,没有在加入成员名单中找到你。';
return;
}
属性.加入成员.splice(位置, 1); //将数组中这个位置的值去除
属性.提示信息 = '退出成功!已经把你从加入名单中去除。';
按引用传递
如果将数组 A 赋值给数组 B,那么赋给 B 的是数组 A 的“引用”。改变数组 A,会导致数组 B 也发生改变,这就是按引用传递。
var 数组 = [2, 3, 3];
var 数组2 = 数组; //将变量『数组』的“引用”赋值给『数组2』
if (数组 === 数组2) {
//为真,会进入if里面
}
数组.push(3);
//对变量『数组』进行操作,会导致『数组2』也发生变化,这就是“按引用传递”
//数组和数组2的值现在都是[2, 3, 3, 3]
if (数组 === 数组2) {
//依然为真,因为对于数组而言,『===』比较的是两个临时变量的引用
}
值得注意的是,对于按引用传递的变量,『===』比较的是两个变量的引用。即使两个数组元素相同,但引用不同,『===』判断出的结果也是不等于。
var 数组 = []
if (数组 === []) {
// 不会执行到这里,因为两者引用不同
// [] === [] 恒为 false
}
if (数组.length === 0) {
// 此处会执行,这才是判断空数组的正确方法
}
如果要判断两个数组元素是否相同,得手动通过循环进行判断
var 数组1 = [1, 2, 3];
var 数组2 = [1, 2, 3];
if (数组1 === 数组2) {
// 不会执行到这里,因为两者引用不同
// 数组1和数组2虽然元素相同,但是它们是两个不同的数组对象
}
var 相同 = true;
if (数组1.length === 数组2.length) {
for (var i = 0; i < 数组1.length; i++) {
if (数组1[i] !== 数组2[i]) {
相同 = false;
break;
}
}
} else {
相同 = false;
}
if (相同) {
// 执行到这里,说明数组1和数组2元素相同
}
只有数组和对象才会按引用传递。普通的类型,例如文本、数字,都是按值传递,改变 A 不会改变 B。具体请查看『临时变量』页面中的“按值传递”小节。