数组是存储一系列值的变量。该变量名称,叫做数组名。组成数组的各个变量,叫做数组的元素。用于区分数组的各个元素的数字编号,被称为下标,下标由 0 开始。数组的作用,使用单独的变量名来存储一系列的值。
数组
1、创建及类型
1.1、创建数组
- 使用构造函数创建数组
var arr = new Array("a", "b")
var arr = new Array(3) //只有一个数字时,相当于直接给数组开辟一个length为3的空数组
- 使用字面量(直接量)创建数组
var a = ["a" , "b" ]
console.log(a);
console.log(a.length);
console.log(a[0]);
1.2、数组类型
- 整数数组:var arr = [1, 3, 6, 9]
- 字符串数组:var arr = [“a”, “b”, “c”, “d”]
- 二维数组: var arr = [[“张三”, 20, 100],[“李四”, 19, 80],[“老王”, 18, 95]]
- 对象数组:var arr=[{name: “张三”},{name: “李四”},{name: “王五”}]
2、数组的操作
2.1、push()
- 向数组的末尾添加一个或更多元素,并返回新的长度
- 语法:数组.push(新元素1, 新元素2, …, 新元素X)
- 返回值:数组的新长度
- 插入数组的尾部,不创建新的数组,而是直接修改原有的数组
var arr = ["a", "b", "c"];
var len = arr.push("d", "e")
console.log(len);
2.2、unshift()
- 向数组的开头添加一个或更多元素,并返回新的长度
- 语法:数组.unshift(新元素1, 新元素2, …, 新元素X)
- 返回值:数组的新长度
- 插入数组的头部,不创建新的数组,而是直接修改原有的数组
var arr = ["a", "b", "c"];
var len = arr.unshift("d", "e")
console.log(len);
2.3、shift()
- 把数组的第一个元素从其中删除,并返回第一个元素的值
- 语法:数组.shift()
- 返回值:数组原来的第一个元素的值
- 如果数组是空的,shift() 方法将无任何操作,返回 undefined 值。该方法是直接修改原有的数组
var arr = ["a", "b", "c"];
var val = arr.shift()
console.log(val);
2.4、pop()
- 删除并返回数组的最后一个元素
- 语法:数组.pop()
- 返回值:数组的最后一个元素
- 删除数组的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。该方法是直接修改原有的数组
var arr = ["a", "b", "c"];
var val = arr.pop()
console.log(val);
2.5、splice()
- 向数组中添加及删除元素
- 语法:数组名.splice(值1,值2,值3…值n)
- 值1:必需。规定从何处添加/删除元素。该参数是开始插入和(或)删除的数组元素的下标,必须是数字。
- 值2:必需。规定应该删除多少元素。必须是数字,但可以是 “0”。如果未规定此参数,则删除从值1 开始到原数组结尾的所有元素。
- 值3…值n.:可选。要添加到数组的新元素
- 返回值:把指定的值添加到数组后的新长度
- 直接修改原有的数组
var arr = ['a', 'b', 'c', 'd']
var r = arr.splice(1, 2) // 从下标1开始,删除2个成员,删掉的成员被变量r接收
var r = arr.splice(1, 0, 'x') // 从下标1开始,删除0个成员,添加成员x,删掉的成员被变量r接收
console.log(r)
console.log(arr)
2.6、concat()
- 连接两个或更多的数组,并返回结果
- 语法:数组.concat(数组1, 数组2, …, 数组X)
- 返回值:组合之后的新数组
- 不改变原数组
var arr1 = ['a', 'b']
var arr2 = ['c', 'd']
var arr3 = ['e', 'f']
var arr = arr1.concat(arr2, arr3)
console.log(arr)
console.log(arr1)
console.log(arr2)
console.log(arr3)
2.7、join()
- 把数组的所有元素放入一个字符串里:把数组转换为字符串,用join参数字符串,把数组中的所有元素,连接到一起
- 语法:数组.join(‘连接符’)
- 连接符可以是任意字符串,如果不规定,则默认是逗号(,)
- 返回值:转化后的字符串
- 不改变原数组
var arr = ['hello', 'world', 'aaa']
var str = arr.join('-')
console.log(str)
2.8、reverse()
- 反转数组的元素顺序
- 语法:数组.push(新元素1, 新元素2, …, 新元素X)
- 返回值:把指定的值添加到数组后的新长度
- 直接改变原数组
var arr = ['a', 'b', 'c', 'd']
arr.reverse()
console.log(arr)
2.9、slice()
- 选取数组指定范围的元素
- 语法:数组.slice(begin, end)
- begin:开始位置的下标(从0开始)
- end:结束位置的下标(但该位置的元素本身不包括在内)
- 返回值:原数组中被选择部分组成的新数组
- 不改变原数组
var arr = ['a', 'b', 'c', 'd']
var r = arr.slice(1) // r=["b", "c", "d"], 从下标1开始截取,截取到最后
var r = arr.slice(1, 2) // 从下标1开始,到下标2之前结束
var r = arr.slice(-1) // 截取倒数第一个
console.log(r)
console.log(arr) // slice 没有对元素数组造成影响
3、数组的遍历
数组的遍历过程相当于循环,以下是三种循环方式
- for 循环: for( var i=0; i<arr.length; i++ ){}
for( var i=0,len=arr.length; i<len; i++ ){
console.log( typeof(i), i, arr[i] );
}
- for in 循环:for( var i in arr ){}
for( var i in arr ){
console.log( typeof(i), i, arr[i] );
}
- for of 循环(新版的IE才支持): for( var i of arr ){}
for( var i of arr ){
console.log(i);
}
4、数组的排序
4.1、sort()
用于对数组元素的unicode值进行排序(默认从小到大),语法:数组.sort(排序规则函数),返回值:对数组的引用。请注意,数组在原数组上进行排序,不生成副本
// 都是一位数的比较
var arr = [1, 3, 2, 4, 6, 5];
arr.sort(); // 按字符串 unicode值,由小到达排序
console.log(arr);
// 多位数的比较
var arr = [3, 12, 4];
arr.sort(); // 比较的是 3 1 4 的unicode值,从小到达排序
console.log(arr);
// 自定义排序规则
var arr = [3, 12, 4];
// x和y是数组中相邻的两个成员(一会儿要比较大小的两个成员)
var fn1 = function(x, y){
// 由小到大排序
return x>y
}
var fn2 = function(x, y){
// 由大到小排序
return x<y
}
arr.sort(fn1);
console.log(arr);
// 二维数组的排序
var arr=[["张三", 100],["李四", 60] ,["隔壁老王", 70]];
arr.sort(function(x, y){
return x[1]>y[1]
});
console.log(arr);
// 对象数组的排序
var arr=[
{name: "张三", score:100},
{name: "李四", score:60}
{name: "王五", score:70}
];
arr.sort(function(x, y){
return x[1]>y[1]
});
console.log(arr);
特点:
- 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。
- 如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,若 a 大于 b,则从小到大排序,否则,从大到小排序。
- 备注:火狐浏览器下js中的sort()方法为归并排序;谷歌浏览器下js中的sort()方法,数组长度小于等于22时,用插入排序,其他用快速排序;Ie至今未公布其浏览器下sort()原理
4.2、典型案例
- 冒泡排序:每相邻两个元素大小作比较,不合适,则交换。
初始值:[23, 6, 2, 21, 16]
第一次:23 与 6 比较,23 比 6 大,所以位置交换
[6], 23, [2, 21, 16]
[6, 2], 23, [21, 16]
[6, 2, 21], 23, [16]
[6, 2, 21, 16], 23
第二次:
[2], 6, [21, 16], 23
[2, 6], 21, [16], 23
[2, 6, 16], 21, 23
第三次:
[2], 6, [16], 21, 23
[2, 6], 16, 21, 23
第四次:
[2], 6, 16, 21, 23 完成排序
var arr = [23, 16, 8, 5, 2, 1]
var len = arr.length
for (var i = 0; i < len - 1; i++) {
console.group('i:', i)
// len-1 是因为最后一次操作时,下标[j+1]时会越界
// 上一次循环后,最大值已经确认了,所以这一次的循环,没有必要和最大值比较了,所以减掉i
for (var j = 0; j < len - 1 - i; j++) {
console.group('j:', j)
console.log(arr[j], '>', arr[j + 1])
if (arr[j] > arr[j + 1]) {
// 交换,小的放前面,大的放后面
var tmp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = tmp
}
console.log(arr)
console.groupEnd('------------')
}
console.log(arr)
console.groupEnd('------------')
}
- 选择排序 selectionSort:每一次选择最小的元素,放在前面
初始值:[23, 6, 2, 21, 16]
第一次:找到最小值 2,与 23 做交换
2, [6, 23, 21, 16]
第二次:找到最小值 6,与 6 做交换(位置不动)
2, 6, [23, 21, 16]
第三次:找到最小值 16,与 23 做交换
2, 6, 16, [21, 23]
第四次:找到最小值 21,与 21 做交换(位置不动)
2, 6, 16, 21, [23] 完成排序
for (var i = 0; i < len; i++) {
console.group('i:', i)
// 求数组中的最小值
// 先假设下标0是数组中最小值的下标
var ind = i // 最小值的下标
var min = arr[ind] // 最小值
console.log('ind:', ind, ' min:', min)
// 循环
for (var j = i + 1; j < len; j++) {
console.group('j:', j)
console.log(min, '>', arr[j])
if (min > arr[j]) {
// 如果min大于arr[j],那么表示min不是最小值
ind = j // 更新最小值
min = arr[j]
}
console.log('ind:', ind, ' min:', min)
console.groupEnd('------------')
}
arr[ind] = arr[i]
arr[i] = min
console.log(arr)
console.groupEnd('------------')
}
5、数组的传递
5.1、传递的方式
- 按值传递:指在方法调用时,传递的参数,是按值的拷贝传递
var a = 1;
var b = a; // b=1
a = 2;
// a=2的更改,没有影响到变量b,因为上一行代码中,b=a时,走的是值传递
// 相当于 直接把a所表示的1,赋值给变量b
console.log(b); // 1
- 按引用传递:指在方法调用时,传递的参数,是按值的地址传递
var a = [1, 2];
var b = a; // b = [1,2] :将a的地址,赋值给b
a[0] = "x";
// a[0] = "x"的更改,影响到变量b,因为上一行代码中,b=a时,走的是引用传递,传的是地址
// a[0]改变时,其存储地址内的值跟着改变,b引用时也跟着改变
console.log(b[0]); //x
- 两种传递方式的区别
function fn(a){ // var a = 5 // 函数内的参数,属于函数中的局部变量
a = 10;
}
var a = 5;
fn(a);
console.log(a); //5
var arr = [1, 2];
function fn(arr){ // var arr=全局变量arr指向堆中数据的地址
arr[0] = 'x';
}
fn(arr);
console.log(arr[0]); //x