1、Array的构造器
Array构造器用于创建一个新数组,当然我们可以直接使用对象字面量的方式创建一个数组,比如var a = [],但是,使用Array是有区别的,比如我想创建一个长度为6的空数组,如下:
// 使用 Array 构造器,可以自定义长度
var a = Array(6); // [empty × 6]
// 使用对象字面量
var b = [];
b.length = 6; // [undefined × 6]
ES6 新增的构造方法:Array.of 和 Array.from
2、Array.of:
Array.of 用于将参数依次转化为数组中的一项,然后返回这个新数组,而不管这个参数是数字还是其他。它基本上与 Array构造器功能一致,唯一的区别就在单个数字参数的处理上。
比如,在下面的这几行代码中,你可以看到区别:当参数为两个时,返回的结果是一致的;当参数是一个时,Array.of会把参数变成数组里的一项,而构造器则会生成长度和第一个参数相同的空数组
Array.of(8.0); // [8]
Array(8.0); // [empty × 8]
Array.of(8.0, 5); // [8, 5]
Array(8.0, 5); // [8, 5]
Array.of("8"); // ["8"]
Array("8"); // ["8"]
3、Array.from
用法1:Array.from (obj, mapFn)
obj指的是数组对象、类似数组对象或者是set对象,map指的是对数组中的元素进行处理的方法。
//将数组中布尔值为false的成员指为0
Array.from([1, , 2, 3, 3], (x) => x || 0); //[1,0,2,3,3]
//将一个类似数组的对象转为一个数组,并在原来的基础上乘以2倍
let arrayLike = { 0: "2", 1: "4", 2: "5", length: 3 };
Array.from(arrayLike, (x) => x * 2); //[4,8,10]
//将一个set对象转为数组,并在原来的基础上乘以2倍
Array.from(new Set([1, 2, 3, 4]), (x) => x * 2); //[2,4,6,8]
用法2:Array.from ({length:n}, Fn)
Array.from({ length: 3 }, () => "jack"); //["jack", "jack", "jack"]
Array.from({ length: 3 }, (item) => (item = { name: "shao", age: 18 })); //[{'name':'shao','age':18}, {'name':'shao','age':18}, {'name':'shao','age':18}]
Array.from({ length: 2 }, (v, i) => (item = { index: i })); //生成一个index从0到4的数组对象[{index: 0},{index: 1}]
用法3:Array.from(string)
Array.from("abc"); //['a','b','c']
4、Array的判断
Array.isArray 用来判断一个变量是否为数组类型
ES5之前判断一个变量是否为数组:
var a = [];
// 1.基于instanceof
a instanceof Array;
// 2.基于constructor
a.constructor === Array;
// 3.基于Object.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(a);
// 4.基于getPrototypeOf
Object.getPrototypeOf(a) === Array.prototype;
// 5.基于Object.prototype.toString
Object.prototype.toString.apply(a) === "[object Array]";
5、数组改变自身的方法:
数组会改变自身的方法一共有9个 分别为:pop,push,shift,unshift,splice,reverse,sort,以及两个ES6新增的方法 copyWithin 和 fill
// pop方法
var array = ["cat", "dog", "cow", "chicken", "mouse"];
var item = array.pop();
console.log(array); // ["cat", "dog", "cow", "chicken"]
console.log(item); // mouse
// push方法
var array = ["football", "basketball", "badminton"];
var i = array.push("golfball");
console.log(array);
// ["football", "basketball", "badminton", "golfball"]
console.log(i); // 4
// reverse方法
var array = [1, 2, 3, 4, 5];
var array2 = array.reverse();
console.log(array); // [5,4,3,2,1]
console.log(array2 === array); // true
// shift方法
var array = [1, 2, 3, 4, 5];
var item = array.shift();
console.log(array); // [2,3,4,5]
console.log(item); // 1
// unshift方法
var array = ["red", "green", "blue"];
var length = array.unshift("yellow");
console.log(array); // ["yellow", "red", "green", "blue"]
console.log(length); // 4
// sort方法
var array = ["apple", "Boy", "Cat", "dog"];
var array2 = array.sort();
console.log(array); // ["Boy", "Cat", "apple", "dog"]
console.log(array2 == array); // true
// 排序:
array.sort((a, b) => a - b);
// splice方法
var array = ["apple", "boy"];
var splices = array.splice(1, 1);
console.log(array); // ["apple"]
console.log(splices); // ["boy"]
// copyWithin方法
var array = [1, 2, 3, 4, 5];
var array2 = array.copyWithin(0, 3);
console.log(array === array2, array2); // true [4, 5, 3, 4, 5]
// fill方法
var array = [1, 2, 3, 4, 5];
var array2 = array.fill(10, 0, 3);
console.log(array === array2, array2);
// true [10, 10, 10, 4, 5], 可见数组区间[0,3]的元素全部替换为10
6、数组不改变自身的方法:
数组不改变自身的方法也有9个:分别是 concat,join,slice,toString,toLocaleString,indexOf,lastIndexOf,未形成标准的toSource,以及ES7新增的方法includes
// concat方法
var array = [1, 2, 3];
var array2 = array.concat(4, [5, 6], [7, 8, 9]);
console.log(array2); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(array); // [1, 2, 3], 可见原数组并未被修改
// join方法
var array = ["We", "are", "Chinese"];
console.log(array.join()); // "We,are,Chinese"
console.log(array.join("+")); // "We+are+Chinese"
// slice方法
var array = ["one", "two", "three", "four", "five"];
console.log(array.slice()); // ["one", "two", "three","four", "five"]
console.log(array.slice(2, 3)); // ["three"]
// toString方法
var array = ["Jan", "Feb", "Mar", "Apr"];
var str = array.toString();
console.log(str); // Jan,Feb,Mar,Apr
// tolocalString方法
var array = [{ name: "zz" }, 123, "abc", new Date()];
var str = array.toLocaleString();
console.log(str); // [object Object],123,abc,2016/1/5 下午1:06:23
// indexOf方法
var array = ["abc", "def", "ghi", "123"];
console.log(array.indexOf("def")); // 1
// includes方法
var array = [-0, 1, 2];
console.log(array.includes(+0)); // true
console.log(array.includes(1)); // true
var array = [NaN];
console.log(array.includes(NaN)); // true
// 强调:slice 不改变自身,而 splice 会改变自身。其中,slice的语法是:arr.slice([start[, end]]),而 splice的语法是:arr.splice(start,deleteCount[, item1[, item2[, …]]])。
//我们可以看到从第二个参数开始,二者就已经有区别了,splice第二个参数是删除的个数,而 slice的第二个参数是 end的坐标(可选)。
7、 数组遍历的方法
不会改变自身的遍历方法一共有12个,分别是forEach,every,some,filter,map,reduce,reduceRighrt以及ES6新增方法 entries,find,findIndex,keys,values
// forEach方法
var array = [1, 3, 5];
var obj = { name: "cc" };
var sReturn = array.forEach(function (value, index, array) {
array[index] = value;
console.log(this.name); // cc被打印了三次, this指向obj
}, obj);
console.log(array); // [1, 3, 5]
console.log(sReturn); // undefined, 可见返回值为undefined
// every方法
var o = { 0: 10, 1: 8, 2: 25, length: 3 };
var bool = Array.prototype.every.call(
o,
function (value, index, obj) {
return value >= 8;
},
o
);
console.log(bool); // true
// some方法
var array = [18, 9, 10, 35, 80];
var isExist = array.some(function (value, index, array) {
return value > 20;
});
console.log(isExist); // true
// map 方法
var array = [18, 9, 10, 35, 80];
array.map((item) => item + 1);
console.log(array); // [19, 10, 11, 36, 81]
// filter 方法
var array = [18, 9, 10, 35, 80];
var array2 = array.filter(function (value, index, array) {
return value > 20;
});
console.log(array2); // [35, 80]
// reduce方法
var array = [1, 2, 3, 4];
var s = array.reduce(function (previousValue, value, index, array) {
return previousValue * value;
}, 1);
console.log(s); // 24
// ES6写法更加简洁
array.reduce((p, v) => p * v); // 24
// reduceRight方法 (和reduce的区别就是从后往前累计)
var array = [1, 2, 3, 4];
array.reduceRight((p, v) => p * v); // 24
// entries方法
var array = ["a", "b", "c"];
var iterator = array.entries();
console.log(iterator.next().value); // [0, "a"]
console.log(iterator.next().value); // [1, "b"]
console.log(iterator.next().value); // [2, "c"]
console.log(iterator.next().value); // undefined, 迭代器处于数组末尾时, 再迭代就会返回undefined
// find & findIndex方法
var array = [1, 3, 5, 7, 8, 9, 10];
function f(value, index, array) {
return value % 2 == 0; // 返回偶数
}
function f2(value, index, array) {
return value > 20; // 返回大于20的数
}
console.log(array.find(f)); // 8
console.log(array.find(f2)); // undefined
console.log(array.findIndex(f)); // 4
console.log(array.findIndex(f2)); // -1
// keys方法
[...Array(10).keys()]; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[...new Array(10).keys()]; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// values方法
var array = ["abc", "xyz"];
var iterator = array.values();
console.log(iterator.next().value); //abc
console.log(iterator.next().value); //xyz
// 以上,forEach没有返回值, every、some 返回值为Boolean, map、filter、reduce默认返回操作过的数组
总结:
数组分类/标准 | 改变自身的方法 | 不改变自身的方法 | 遍历方法(不改变自身) |
ES5及以前 | pop,push,reverse,shift, sort,splice,unshift | concat,join,slice,toString, toLocateString,indexOf, | forEach,every,some,filter,map, reduce,reduceRight |
ES6/7/8 | copyWithin,fill | includes,toSource | entries,find,findIndex,keys,values |
数组的各方法基本讲解完毕,这些方法之间存在很多共性,如下:
所有插入元素的方法,比如 push、unshift一律返回数组新的长度;
所有删除元素的方法,比如 pop、shift、splice一律返回删除的元素,或者返回删除的多个元素组成的数组;
部分遍历方法,比如 forEach、every、some、filter、map、find、findIndex,它们都包含 function(value,index,array){} 和 thisArg这样两个形参。