Array.from()

Array.from() 方法从类似数组(array-like)或可迭代对象(iterable)创建一个新的数组实例(包括ES6新增的数据结构Set和Map)。

Array.from(arrayLike[, mapFn[, thisArg]])

如下是一个类数组的对象,Array.from将它转换为一个真正的数组。

// [].slice.call(arrayLike); es5
let arrayLike = {
'0': 'a',
'1': 'b',
'8': 'c',
length: 5
}
var arr1 = Array.from(arrayLike);
console.log(arr1);

结果是一个5个元素的数组,其中第一个元素是a,第二个元素是b,第三第四第五个元素是undefined。length制定数组的长度,没有这个属性数组长度为0,超过数组索引的值无效,如上述的8。

实际应用中,常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments对象。Array.from都可以将他们转换为真正的数组。

// NodeList对象
let ps = document.querySelectAll('p');
Array.from(ps).forEach(function(p) {
console.log(p);
})
// arguments对象
(function(){]
var args = Array.from(arguments);
console.log(args);
})(1,2,3)

事实上,只要是部署了Iterator接口的数据结构,Array.from都能将其转换为数组。比如字符串、Set、Map,以及自定义的Iterator。

对于还没有部署该方法的浏览器,可以用Array.prototype.slice方法替代。

const toArray = (() => Array.from ? Array.from : [].slice.call(obj))();

Array.from() 方法有一个可选参数 mapFn,让你可以在最后生成的数组上再执行一次 map 方法后再返回。也就是说 Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg), 除非创建的不是可用的中间数组。

Array.from([1, 2, 3], x => x * x); // [1, 4, 9]
Array.from([1, 2, 3], (x, k) => k); // [0, 1, 2] 返回索引

如果mapFn函数中用到了this关键字,还可以传入第三个参数,用来绑定this。

Array.from()的另一个应用是,将一个字符串转换为数组,然后返回字符串的长度。因为它能正确处理各种Unicode字符,可以避免JavaScript将大于\uFFFF额Unicode字符算作多个字符的bug。

function countSymbols(string) {
return Array.from(string).length;
}

Array.of()

Array.of方法用于将一组值转换为数组。

Array.of(element0[, element1[, ...[, elementN]]])
Array.of(1, 2, 3); // [1, 2, 3]

此方法是弥补数组构造函数的不足,因为当数组参数只有一个的时候会被当做数组的长度而不会第一个元素看待。

console.log(new Array()); // []
console.log(new Array(1)); // [undefined]
console.log(new Array(1,2)); // [1, 2]

Array.of方法可以使用下面的代码模拟实现:

function ArrayOf() {
return [].slice.call(arguments);
}

Array.prototype.copyWithin()

copyWithin() 方法会浅拷贝数组的部分元素到同一数组的不同位置,且不改变数组的大小,返回该数组。
copyWithin 函数是设计为通用的,其不要求其 this 值必须是一个数组对象。

arr.copyWithin(target, start = 0, end = this.length)
  • target: 必须,表示复制序列到该位置。
  • start: 开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
  • 开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。

以上参数都是以0为基底。

// 从3号索引开始,从位置0开始复制
[1, 2, 3, 4, 5].copyWithin(0, 3); // [4, 5, 3, 4, 5]
// -2相当于3
[1, 2, 3, 4, 5].copyWithin(0, -2, -1); //[4, 2, 3, 4, 5]
// this不需要指向数组
[].copyWithin.call({length: 5, 3: 1}, 0, 3); // {0: 1, 3: 1, length: 5}

Array.prototype.find()和Array.prototype.findIndex()

正如其名,数组实例的find方法,用于找出第一个符合条件的数组元素。该函数接受一个函数参数,函数有三个参数,如下:

[1, 2, 3, 4, 5].find((item, index, arr) => item > 3); // 4

如果找不到符合条件的值返回undefined。

findIndex方法,找到第一个符合条件元素的索引。参数和find方法一样。

[1, 2, 3, 4, 5].findIndex((item, index, arr) => item > 3); // 3

如果找不到符合条件的值返回-1。

另外这两个方法都可以发现NaN,弥补了数组的IndexOf方法的不足。

[NaN].indexOf(NaN); // -1
[NaN].findIndex(y => Object.is(NaN, y)); // 0

Array.prototype.fill()

fill方法将一个数组的所有元素从开始索引填充到具有静态值的结束索引。
fill 方法故意被设计成通用方法, 也就是说它不需要 this 值必须是个数组对象, 类数组对象也是可以调用该方法的。

fill 方法接受三个参数 value, start 以及 end. start 和 end 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值.

如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值. 如果 end 是个负数, 则结束索引会被自动计算成为 length+end.

具体要填充的元素区间是 [start, end) , 一个半开半闭区间。

[1, 2, 3].fill(4)            // [4, 4, 4]
[1, 2, 3].fill(4, 1) // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2) // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1) // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2) // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN) // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({length: 3}, 4) // {0: 4, 1: 4, 2: 4, length: 3}

Array.prototype.keys()/values()/entries()

这三个方法用于遍历数组。它们都返回一个遍历器对象,可用for…of遍历,唯一的区别是:keys()是对键值的键名的遍历,values()是对键值的遍历,entries()是对键值对的遍历。

for(var index of ['a', 'b'].keys()) {
console.log(index); // 0 1
}

for(var value of ['a', 'b'].values()) {
console.log(value); // 'a' 'b'
}

for(var [index, value] of ['a', 'b'].entries()) {
console.log([index, value]);
// [0, 'a'] [1, 'b']
}

如果不使用for…of遍历,可以手动调用遍历器对象的next方法进行遍历。

let arr = ['a', 'b', 'c'];
let entries = arr.entries();

console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
console.log(entries.next().value); // undefined

Array.prototype.includes()

该方法返回一个布尔值,表示一个数组中是否存在某个元素。该方法属于ES7,但是Babel转码器已经支持。

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[NaN].includes(NaN); // true

该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true

该方法类似于使用indexOf()判断一个元素是否在数组。但是这个方法有两个好处:

  • 语义更清晰,使用indexOf()需要与-1比较
  • 可以判断NaN。indexOf()内部使用===判断相等,而NaN !== NaN

数组的空位

空位表示数组的某个位置没有任何值。比如,Array构造的函数都是空位(一个参数)。

var arr = new Array(3);
0 in arr; // false
-------------------

0 in [undefined]; //true, 其中0是数组的键名,即索引

ES5对空位的处理不一致,大多数情况下忽略空位:

  • forEach()、filter()、every()、some()都会跳过空位
  • map()会掉过空位,但会保留这个值
  • join()和toString()会将空位视为undefined,而将undefined和null视为空字符串
  • etc…由于对空位处理非常不同意,所以建议避免空位

数组推导

数组推导提供了简洁写法,允许直接通过现有数组生成新数组。为了让其支持所有数据结构(内部调用iterator对象),不像现在之调用数组,所以将其推迟到ES7。Babel转码器已经支持这个功能。

略。

参考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

es6.ruanyifeng.com

更多相关文章

  1. 在关联数组中移动元素[重复]
  2. JavaScript中的数学对象中的方法
  3. JavaScript——数组(三)数组方法汇总
  4. 如何通过ajax将javascript数组传递给YII动作
  5. 与jQuery ajax post方法相比,fetch方法没有按预期发布
  6. 在ExtJS中调用超类方法的更好方法
  7. 在Javascript中将带有空格的字符串数组转换为小写,然后在Webkit中
  8. contains和compareDocumentPosition 方法来确定是否HTML节点间的
  9. 返回指定时间段相同间隔数组

随机推荐

  1. 面试官最爱问你的,网络分层中每一层有哪些
  2. 动画 :相识数组与链表两兄弟
  3. 【工具】历史文章分类汇总-V4 | Python数
  4. 偷学Python二十六|OS.path模块的详细使用
  5. 51CTO学员---沿着前人脚步追寻pmp的5个A
  6. 面试必知必会|理解堆和堆排序
  7. Numpy中Meshgrid函数介绍及2种应用场景
  8. 二叉树及其四大遍历
  9. 大学三年,写下 “万字” 兼职经历,这就是你
  10. 给Python代码加上酷炫进度条的几种姿势