数组
文章目录
ECMAScript 数组也是 一组有序的数据,但跟其他语言不同的是,数组中 每个槽位可以存储任意类型的数据。ECMAScript 数组也是 动态大小的,会随着数据添加而自动增长。
1. 数组定义
1.1 数组字面量
var arr = [];
数组字面量是在中括号[]
中包含以逗号分割的元素列表。
var value = [1, 2, 'a', 'b'];
1.2 Array构造函数
var arr = new Array();
var arr = new Array(1, 2, 3, 4, 5); //arr = [1, 2, 3, 4, 5];
Array构造函数与数组字面量的区别在于,当Array构造函数只传一个数的时候,这个数只能是一个正整数,构造函数会将这个数看作数组长度,并构建该长度的稀松数组。
var arr = new Array(10); //arr = [undefined × 10];
var arr = new Array(10.2); //报错
var arr1 = [10]; //arr1 = [10];
1.3 关于数组空位
使用数组字面量初始化数组时,可以使用一串逗号来创建空位(hole)。
var arr = [,,,,,];
全逗号的数组有些特殊,表示一个空位数组,且包含5个元素,[undefined × 5]
;
var arr = [1,,,,,];
表示[1, undefined × 4]
;
var arr = [1,,,,,5];
表示[1, undefined × 4, 5]
;
var arr = [1, 2, , , 4];
表示创建数组[1, 2, undefined, undefined, 4]
。
这种存在有空隙的数组,称为稀松数组。
1.4 ES6新增创建数组的静态方法(了解)
- Array.from()
用于将类数组结构转换为数组实例。
//字符串
console.log(Array.from("Matt")); //["M","a","t","t"]
//arguments对象可以被轻松转换成数组
function getArgsArray() {
return Array.from(arguments);
}
console.log(getArgsArray(1,2,3,4)); //[1,2,3,4]
//类数组
var arrayLikeObject = {
0 : 1,
1 : 2,
2 : 3,
length : 3
};
console.log(Array.from(arrayLikeObject)); //[1,2,3]
- Array.of()
用于将一组参数转换为数组。
console.log(Array.of(1,2,3,4)); //[1,2,3,4]
console.log(Array.of(undefined)); //[undefined]
2. 数组的读和写
arr[num]
不可以溢出读,但不会报错,结果是undefined。即,若一个数组的长度是10,当你读该数组的第11位时,系统也并不会报错,而会返回undefined。
arr[num] = xxx;
可以溢出写。
数组的读写性质类似于对象,而数组本身就是一种特殊的对象,与对象没有太大的分别。
3. 数组的常用方法(基于ES3.0)
3.1 改变原数组
3.1.1 push
在数组的最后一位添加任意类型的数据,可以一次添加多个数据
var arr = [1,2];
arr.push(1,2,3,4); //arr = [1, 2, 1, 2, 3, 4]; return 6
push会返回该数组的长度。
模拟push的方法
Array.prototype.myPush = function () {
for(var i = 0; i < arguments.length; i ++) {
this[this.length] = arguments[i];
}
return this.length;
}
3.1.2 pop
把数组的最后一位剪切出去。
传参无效,括号中不需要写入任何参数。
var arr = [1,2,3];
var num = arr.pop();
console.log(arr); //[1,2]
console.log(num); //3
3.1.3 shift
把数组的首位剪切出去。
传参无效。
var arr = [1, 2, 3];
var num = arr.shift();
console.log(arr); //[2, 3]
console.log(num); //1
3.1.4 unshift
在数组的首位添加任意类型的数据,可以一次添加多个数据。同push,会返回数组长度。
var arr = [1, 2, 3];
arr.unshift(0); //4
console.log(arr); //[0, 1, 2, 3]
arr.unshift(-1,-2); //6
console.log(arr); //[-1, -2, 0, 1, 2, 3]
模拟unshift:
思路1,新建一个数组,把实参列表先放进去,再把原数组push进去
Array.prototype.myUnshift1 = function () {
var arrCon = [];
for(var i = 0; i < arguments.length; i ++){
arrCon[i] = arguments[i];
}
for(var i = 0; i < this.length; i ++){
arrCon[arrCon.length] = this[i];
}
for(var j = 0; j < arrCon.length; j ++){
this[j] = arrCon[j];
}
return this.length;
}
思路2,利用倒序
Array.prototype.myUnshift = function () {
this.reverse();
for(var i = 0; i < arguments.length; i ++){
this[this.length] = arguments[i];
}
this.reverse();
return this.length;
}
3.1.5 reverse
将原数组倒序。
var arr = [1, 2, 3];
arr.reverse(); //[3, 2, 1]
console.log(arr); //[3, 2, 1]
3.1.6 splice
arr.splice(从第几位开始,截取多少长度,在切口处添加新的数据)
例如:
var arr = [1,1,2,2,3,3];
var num = arr.splice(1,2); //num = [1,2]; arr = [1,2,3,3];
var arr = [1,1,2,2,3,3];
var num = arr.splice(1,1,0,0,0); //num = [1]; arr = [1,0,0,0,2,2,3,3];
若不想将原数组中的内容截取出去,第二位可以是0。注意此时添加数据的位置是在开始位置之前。
var arr = [1,2,3,5];
arr.splice(3,0,4); //arr = [1,2,3,4,5];
第一个参数a为负数时,相当于从arr.length - a
位开始。表示倒数第a位。
var arr = [1,2,3,4];
var num = arr.splice(-1,1); //num = 4; arr = [1,2,3];
3.1.7 sort
sort()
函数会按照字符串顺序对值进行升序排列。
即,如果调用sort()方法没有使用参数,将按照字符编码的顺序进行排序,且默认为升序排序。
var arr = [3,8,1,6,5,4];
arr.sort(); //arr = [1,3,4,5,6,8];
若要降序,多加一个reverse()
。
var arr = [3,8,1,6,5,4];
arr.sort().reverse(); //arr = [8,6,5,4,3,1];
不过,如果数字按照字符编码来排序,则 “25” 大于 “100”,因为 “2” 大于 “1”。
var arr = [2,3,10,12,1];
arr.sort(); //arr = [1,10,12,2,3];
若想对数字正确排序,则需要提供比较函数,即将一个比较函数的函数声明作为sort()
方法的参数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。
比较函数的规则:
- 必须写两个形参
- 看返回值
1)当返回值为负数时,前面的数放在前面
2)当返回值为正数时,前面的数放在后面
3)当返回值为0时,不动
3.1.7.1 升序
var arr = [1,3,5,4,10];
arr.sort(function (a, b) {
if(a > b) {
return 1;
} else {
return -1;
}
}); //arr = [1,3,4,5,10];
参数的比较顺序同冒泡排序,先拿第0位与第1到4位依次比较,再拿第1位与第2到4位依次比较,再拿第2位与第3,4位比较,最后拿第3位与第4位比较。
比较的过程中,返回值为正数,则两个数的顺序调换。
简化写法
var arr = [3,2,10,12,1];
arr.sort(function (a, b) {return a - b;}); //arr = [1,2,3,10,12];
对象按某个属性排序:
var aaa = {
name : "aaa",
age : 12,
sex : "male"
};
var bbb = {
name : "bbb",
age : 10,
sex : "female"
};
var ccc = {
name : "ccc",
age : 20,
sex : "male"
};
var arr = [aaa, bbb, ccc];
arr.sort(function (a, b) {return a.age - b.age});
console.log(arr);
例:对数组中的字符串按字节长度排序(升序)
function retBytes(str) {
var num = str.length;
for(var i = 0; i < str.length; i ++){
if(str.charCodeAt(i) > 255) {
num ++;
}
}
return num;
}
var arr = ["asdasda34","asd", "asd数", "数", "a"];
arr.sort(function(a,b){return retBytes(a) - retBytes(b)});
console.log(arr);
3.1.7.2 降序
若想降序
arr.sort(function (a, b) {
if(a < b) {
return 1;
} else {
return -1;
}
});
简化写法
arr.sort(function (a, b) {return b - a;});
3.1.7.3 乱序
给一个有序数组,乱序
var arr = [1,2,34,455,9];
arr.sort(function (a, b) {
return Math.random() - 0.5;
});
Math.random()
生成一个(0,1)之间的随机数。
3.2 不改变原数组
3.2.1 concat
将两个数组连接到一块,但是不改变两个原数组。
var arr = [1,2,3,4];
var arr1 = [5,6];
arr.concat(arr1); //[1,2,3,4,5,6]
//执行之后,arr和arr1并没有改变
不传参可以实现对原数组的复制
例如,数组arr=[1,2,3],此时我想要一个arr的副本,则可以let arrCopy = arr.concat();
3.2.2 toString
将数组转化为字符串
var arr = [1,2,3];
arr.toString(); //"1,2,3"
3.2.3 slice
两个参数的情况:slice(从该位开始截取,截取到该位)
var arr = [1,2,3,4,5,6];
var newArr = arr.slice(1,3); //newArr = [2,3];
一个参数的情况:slice(从该位开始截取,一直到最后)
var arr = [1,2,3,4,5,6];
var newArr = arr.slice(1); //newArr = [2,3,4,5,6];
var newArr1 = arr.slice(-4); //相当于arr.slice(2),newArr1 = [3,4,5,6];
没有参数的情况:slice()
,整个截取。在类数组中可以使用slice空截,将类数组转换为数组。
3.2.4 join
将数组的每一位通过括号中的字符连接起来,并返回字符串。
若join()
不传参数,则用逗号连接数组元素。
var arr = [1,2,3,4,5];
var str = arr.join("-"); //str = "1-2-3-4-5"
split不是数组的方法,而是字符串的方法,其作用正好与join相反。
按照括号中的字符将字符串拆分成若干数组。
var arr = [1,2,3,4,5];
var str = arr.join("-");
var arr1 = str.split("-"); //arr1 = ["1","2","3","4","5"];
var arr2 = str.split("3"); //arr2 = ["1-2-","-4-5"];
join的应用:将多个字符串连接到一起
1.加号运算符
var str = "alibaba";
var str1 = "baidu";
var str2 = "tencent";
var str3 = "toutiao";
var str4 = "wangyi";
var str5 = "xiaowang";
var strFin = "";
strFin = str + str1 + str2 + str3 + str4 + str5;
但是这种方法需要多次调用栈内存,会稍微影响运行速度。
2.join()
var str = "alibaba";
var str1 = "baidu";
var str2 = "tencent";
var str3 = "toutiao";
var str4 = "wangyi";
var str5 = "xiaowang";
var arr = [str, str1, str2, str3, str4, str5];
var strFin = arr.join("");
使用join的方法时,速度会很快。
3.3 遍历数组
for of
是ES6中新增的用于遍历拥有迭代器对象的集合,但是不能遍历对象。
var arr = Array.from([,,,]);
for(var vel of arr){
console.log(vel == undefined);
}
//true
//true
//true