一.数组创建
1、Array.from()方法
Array.from 方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
let arrayLike = {
"0": "a",
"1": "b",
"2": "c",
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
//任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
//扩展运算符只能对部署 Iterator 接口的类数组转换为真正的数组
//console.log([...arrayLike]); // 报错 TypeError: Cannot spread non-iterable object
//Array.from还可以接受第二个参数,作用类似于数组的map方法
var map = Array.from(arrayLike, x => x + x);
console.log(map); // ["aa", "bb", "cc"]
2、Array.of()方法
Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。即Array.of 方法用于将一组值,转换为数组。弥补数组构造函数 Array()的不足。因为参数个数的不同,会导致 Array()的行为有差异
//如下代码看出差异
Array.of(3); // [3]
Array.of(3, 11, 8); // [3,11,8]
new Array(3); // [, , ,]
new Array(3, 11, 8); // [3, 11, 8]
// Array.of方法可以用下面的代码模拟实现。
function ArrayOf() {
return [].slice.call(arguments);
}
二.数组填充
Array.fill()方法
fill()方法,使用自己想要的参数替换原数组内容,但是会改变原来的数组。
该方法有三个参数: fill(value, start, end) value:想要替换的内容。 start:开始位置(数组的下标),可以省略。 end:替换结束位置(数组的下标),如果省略不写就默认为数组结束。
使用小例
1.采用一个默认值填初始化数组
const a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a1.fill(7)
console.log('%s', a1)
运行结果:
7,7,7,7,7,7,7,7,7,7,7
2.制定开始和结束位置填充。
实际填充结束位置是前一位。
const a2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a2.fill(7, 2, 5)
console.log('%s', a2)
运行结果:
1,2,7,7,7,6,7,8,9,10,11
3.结束位置省略。
从起始位置到最后。
const a3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a3.fill(7, 2)
console.log('%s', a3)
运行结果:
1,2,7,7,7,7,7,7,7,7,7
三.数组遍历
1、Array.prototype.forEach
forEach方法最大的好处就是便于使用,而且不用定义额外的参数变量。
var a = [1,2,3];
a.forEach(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3],该参数貌似没什么用
})
但是从效率以及性能角度来说它是劣于原始for循环的,而且也不能强制return结束循环,原因如下: forEach循环一看就是通过回调函数来提供参数的,而回调函数在JS中是闭包的一种,闭包的作用是用来生成私有作用域的,所以,每一个回调函数都是一个独立的作用域,都拥有自己独立的存储空间,互不影响,而且内部变量还不及时释放,这也就是为什么在能不用闭包的情况下就不要用闭包的原因,而在闭包中return的话,也只是在当前回调函数中返回了,可是forEach中的其他的回调函数(闭包)仍然存在,所以,导致return是没办法结束循环的。下面写一个forEach循环实现例子供大家参考理解:
Array.prototype.forEachCopy = function(callback){
var arr = this;
for(var i=0;i<arr.length;i++){
callback(arr[i],i,this);
}
}
var a = [1,2,3];
a.forEachCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
})
2、Array.prototype.map
map和forEach不同,在forEach中return语句是没有任何效果的,而map则可以改变当前循环的值,并且最终会返回一个新的被改变过值之后的数组(map如果不用return就和forEach一样了),由于这个特性,map一般用来处理需要修改某一个数组的值。
var a = [1,2,3];
var b = a.map(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
return value+1;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 2, 3, 4 ]
map和forEach在其他的方面都是一样的,也不能return结束循环等特性。像这样:
Array.prototype.mapCopy = function(callback){
var arr = this;
var arrCopy = [];
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
arrCopy.push(cbValue);
}
return arrCopy;
}
var a = [1,2,3];
var b = a.mapCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
return value+1;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 2, 3, 4 ]
3、Array.prototype.filter
例子
var a = [1,2,3];
var b = a.filter(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
if(value === 3){
return false;
}
return true;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 1,2 ]
filter和map不同,map目的是为了改变值,而filter目的是为了去掉不要的值,在循环的时候如果返回的是false那么就表示本次循环的不添加该值,返回true则相反是表示要添加到新建的数组中,下面写一个filter循环实现例子:
Array.prototype.filterCopy = function(callback){
var arr = this;
var arrCopy = [];
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
if(cbValue){
arrCopy.push(arr[i]);
}
}
return arrCopy;
}
var a = [1,2,3];
var b = a.filterCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 结尾依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
if(value === 3){
return false;
}
return true;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 1,2 ]
4、Array.prototype.reduce
例子
var a = [1,2,3];
var b = a.reduce(function (count, value,key,arry) {
console.log(count); // 结果依次为0,1,3
console.log(value); // 结果依次为1,2,3
console.log(key); // 结果依次为0,1,2
console.log(arry) // 三次结果都为[1,2,3]
return count + value;
},0);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b) // 结果为6
reduce的不同之处在于累加,和其他几个内置方法不同的地方,它的第二个参数不是this对象,而是初始累加值(如果不设置的话数组会乱掉),而且回调函数的的个数也不同,比其他的多了一个,而且还在在开始的多加了一个参数,第一个参数记录的是上一次循环的累加值,下面写一个reduce循环实现例子:
Array.prototype.reduceCopy = function(callback,countInit){
var arr = this;
for(var i=0;i<arr.length;i++){
var cbValue = callback(countInit,arr[i],i,this);
countInit = cbValue;
}
return countInit;
}
var a = [1,2,3];
var b = a.reduceCopy(function (count, value,key,arry) {
console.log(count); // 结果依次为0,1,3
console.log(value); // 结果依次为1,2,3
console.log(key); // 结果依次为0,1,2
console.log(arry) // 三次结果都为[1,2,3]
return count + value;
},0);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b) // 结果为6
暂时先记录这么多,以后再补充。