Array Iterator可遍历对象
entries()
方法返回一个新的Array Iterator对象
什么是Array Iterator对象?
const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();
console.log(iterator1.next());
console.log(iterator1.next());
console.log(iterator1.next());
console.log(iterator1.next());
打印结果:
> Object { value: Array [0, "a"], done: false }
> Object { value: Array [1, "b"], done: false }
> Object { value: Array [2, "c"], done: false }
> Object { value: undefined, done: true }
keys()
keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。
const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
输出:
> Object { value: 0, done: false }
> Object { value: 1, done: false }
> Object { value: 2, done: false }
> Object { value: undefined, done: true }
keys()和Object.keys()的区别?
索引迭代器会包含那些没有对应元素的索引,例如:
var arr = ["a", , "c"];
const iterator = array1.keys();
console.log([...iterator]) // [0,1,2]
console.log(Object.keys(arr)) // ['0','1']
values()
返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
输出:
> Object { value: "a", done: false }
> Object { value: "b", done: false }
> Object { value: "c", done: false }
> Object { value: undefined, done: true }
或者
for (const value of iterator) {
console.log(value);
}
> "a"
> "b"
> "c"
数组的操作
unshift()
将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。
const array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// output: 5
console.log(array1);
// output: [4, 5, 1, 2, 3]
shift()
从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
const array1 = [1, 2, 3];
const firstElement = array1.shift();
console.log(array1);
// output: [2, 3]
console.log(firstElement);
// output: 1
在while循环中使用shift()
shift() 方法经常用于while loop的环境中。下例中每个循环将要从一个数组中移除下一项元素,直至它成为空数组。
var names = ["Andrew", "Edward", "Paul", "Chris" ,"John"];
while( (i = names.shift()) !== undefined ) {
console.log(i);
}
// Andrew, Edward, Paul, Chris, John
pop()
从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];
plants.pop()
console.log(plants);
//output: Array ["broccoli", "cauliflower", "cabbage", "kale"]
splice()与slice()的区别
slice
是截取一段原数组,返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin
,不包括end
)。原始数组不会被改变。
arr.slice(begin, end)
- begin不传,则从0开始;begin大于数组长度,则返回空数组
- end不传,则到末尾;end大于数组长度,则也到末尾
slice对原数组的拷贝,元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。因为两个对象引用都引用了同一个对象,如果被引用的对象发生改变,则两个数组中的此元素都会发生改变。
slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。例如:
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
splice通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
- start必填。如果大于数组长度 ,则从末尾开始添加内容;如果是负数,则从倒数第N位;如果负数绝对值大于数组长度,则从0开始
- deleteCount不传,则 start之后的所有元素都被删除,包含 start;如果为0或负数,则必须添加一个新元素。
- item1,item2,…,从start开始添加进去的元素,如果不传,则只执行删除操作。
fill()
用一个固定值填充一个数组中从startIndex到endIndex内的全部元素。包括start
,不包括end
。返回修改后的数组。
arr.fill(value,start,end)
- start:可选,默认为0
- end:可选,默认为数组长度
const array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 3)); // output: [1, 2, 0, 4]
console.log(array1.fill(5, 1)); // output: [1, 5, 5, 5]
console.log(array1.fill(6)); // output: [6, 6, 6, 6]
fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。如果start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值;end也是如此。
reverse()
颠倒数组中元素的位置,改变了数组,并返回该数组
const array1 = ['one', 'two', 'three'];
console.log(array1.reverse()) //["three", "two", "one"]
数组的遍历
sort()
- 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
- 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
- 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
- 返回排序后的数组。请注意,数组已原地排序,并且不进行复制。
every()
所有元素都符合,才会返回true,否则返回false。
[12, 5, 8, 130, 44].every(x => x >= 10); // false
回调函数的参数:
- element
- index可选
- array可选
some()
与every对立,只要有一个符合条件就返回true,所有元素都不符合才会返回false
[12, 5, 8, 1, 4].some(x => x > 10); // true
some和includes的区别
some可以变相实现includes的功能:
function includes(arr, val) {
return arr.some(arrVal => val === arrVal);
}
includes参数是传入值,判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
arr.includes(value,fromIndex)
- fromIndex默认为0;如果为负值,则按升序从
array.length + fromIndex
的索引开始搜。
map()
创建一个新数组,返回一个由原数组每个元素执行回调函数的结果组成的新数组。
- 因为map生成一个新数组,当你不打算使用返回的新数组却使用map是违背设计初衷的,请用forEach或者for-of替代。
- 你不该使用map的情况: A)你不打算使用返回的新数组,或/且 B) 你没有从回调函数中返回值。
- callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。
- map 不修改调用它的原数组本身
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1); // output: [2, 8, 18, 32]
数组的展平
flat()
会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
- 参数depth,默认为1,Infinity为任意深度。
- flat() 方法会移除数组中的空项。
// 递归版本的自己实现
function flatten(array) {
var flattend = [];
(function flat(array) {
array.forEach(function(el) {
if (Array.isArray(el)) flat(el);
else flattend.push(el);
});
})(array);
return flattend;
}
flatMap()
首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
返回一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为1。
flatMap和map的区别?
let arr1 = ["it's Sunny in", "", "California"];
arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]
flatMap()其实就是先map()操作然后flat(1)操作。
其他
lastIndexOf()
数组中该元素最后一次出现的索引,如未找到返回-1。从后往前找。
arr.lastIndexOf(searchElement,fromIndex)
- fromIndex默认为
arr.length - 1
,如果该值大于或等于数组的长度,则整个数组会被查找 - 如果为负数,将其值为(
arr.length + fromIndex
)。如果绝对值大于数组长度,则方法返回-1。
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
console.log(animals.lastIndexOf('Dodo'));// output: 3
console.log(animals.lastIndexOf('Dodo',-1));// output: 3
join()
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join('-')) ; // output: "Fire-Air-Water"
参数separator
可选,指定一个字符串来分隔数组的每个元素。默认为’,’。如果separator是空字符串(""),则所有元素之间都没有任何字符。
copyWithin()
浅复制数组的一部分到同一数组中的另一个位置,并返回改变后的数组,不会改变原数组的长度。
arr.copyWithin(target, start, end)
- target是复制序列到这个位置
- start可选,是复制元素的开始位置,默认为0。如果为负数,则为
arr.length+start
- end可选,复制元素的结束位置,默认为
arr.length
。如果为负数,则为arr.length+start
reduce()
reduce() 如何运行
假如运行下段reduce()代码:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
callback 被调用四次,每次调用的参数和返回值如下表:
callback | accumulator | currentValue | currentIndex | array | return value |
---|---|---|---|---|---|
first call | 0 | 1 | 1 | [0, 1, 2, 3, 4] | 1 |
second call | 1 | 2 | 2 | [0, 1, 2, 3, 4] | 3 |
third call | 3 | 3 | 3 | [0, 1, 2, 3, 4] | 6 |
fourth call | 6 | 4 | 4 | [0, 1, 2, 3, 4] | 10 |
由reduce返回的值将是最后一次回调返回值(10)。
你还可以使用箭头函数来代替完整的函数。 下面的代码将产生与上面的代码相同的输出:
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
如果你打算提供一个初始值作为reduce()方法的第二个参数,以下是运行过程及结果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; }, 10 );
callback | accumulator | currentValue | currentIndex | array | return value |
---|---|---|---|---|---|
first call | 10 | 0 | 0 | [0, 1, 2, 3, 4] | 10 |
second call | 10 | 1 | 1 | [0, 1, 2, 3, 4] | 11 |
third call | 11 | 2 | 2 | [0, 1, 2, 3, 4] | 13 |
fourth call | 13 | 3 | 3 | [0, 1, 2, 3, 4] | 16 |
fifth call | 16 | 4 | 4 | [0, 1, 2, 3, 4] | 20 |
这种情况下reduce()返回的值是20。