Array

在 ES6 中新增了很多实用的原生 API,方便开发者对 Array 的操控性更强,如 for...of、from、of、fill、find、findIndex等

二级标题

ES5 中数组遍历方式

let arr = [1, 2, 3, 2, 4]

用for循环

let arr = [1, 2, 3, 2, 4]
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i])
}
  • forEach() 没有返回值,只是针对每个元素调用func

注意
forEach 的代码块中不能使用 break、continue,它会抛出异常。

let arr = [1, 2, 3, 2, 4]
arr.forEach(function(elem, index, array) {
    if (arr[i] == 2) {
        continue
    }
    console.log(elem, index)
})

这个语法看起来要简洁很多,不需要通过索引去访问数组项,然而它的缺点也是很明显,不支持 break、continue 等。


  • map() 返回新的数组,每个元素为调用func的结果
let arr = [1, 2, 3, 2, 4]
let result = arr.map(function(value) {
    value += 1
    console.log(value)
    return value
})
console.log(arr, result)
  • filter() 返回符合func条件的元素数组
let arr = [1, 2, 3, 2, 4]
let result = arr.filter(function(value) {
    console.log(value)
    return value == 2
})
console.log(arr, result)
  • some() 返回boolean,判断是否有元素符合func条件,返回布尔值
let arr = [1, 2, 3, 2, 4]
let result = arr.some(function(value) {
    return value == 4
})
console.log(arr, result)  //arr  1, 2, 3, 2, 4    result  true
  • every() 返回boolean,判断每个元素都符合func条件
let arr = [1, 2, 3, 2, 4]
let result = arr.every(function(value) {
    return value == 2
})
console.log(arr, result)  //arr 1, 2, 3, 2, 4     result false

同样完成刚才的目标,使用 every 遍历就可以做到 break 那样的效果,简单的说 return false 等同于 break,return true 等同于 continue。如果不写,默认是 return false。
注意:every 的代码块中不能使用 break、continue,它会抛出异常。

const arr = [1, 2, 3, 4, 5]
const sum = arr.reduce((pre, item) => {
    return pre + item
}, 0)
console.log(sum) // 15

callback:函数中包含四个参数

  • previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
  • currentValue (数组中当前被处理的元素)
  • index (当前元素在数组中的索引)
  • array (调用的数组)
    initialValue (作为第一次调用 callback 的第一个参数。)
    pre初始值initialValue,之后是计算结束后的返回值,0,0+1,1+2,3+3,6+4;

以上回调被调用5次,每次的参数详见下表


2021-02-23_150641.jpg

如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

  • reduce计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1 
  }
  return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

in 操作符
in 操作检查对象中是否有名为 property 的属性。也可以检查对象的原型,以便知道该属性是否为原型链的一部分。

对于一般的对象属性需要用字符串指定属性的名称

var mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar  // returns true
"model" in mycar // returns true

对于数组属性需要指定数字形式的索引值来表示数组的属性名称(固有属性除外,如length)

// Arrays
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // returns true
3 in trees        // returns true
6 in trees        // returns false
"bay" in trees    // returns false (you must specify the index number,
                  // not the value at that index)
"length" in trees // returns true (length is an Array property)
  • reduce数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

//第二种方式
let arr = [1, 2, 3, 2, 4]
let res = arr.reduce(function(prev, cur) {
    prev.indexOf(cur) == -1 && prev.push(cur)
    return prev
}, [])
console.log(res)
  • reduce将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
    return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
  • reduce将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
  • reduce将多维数组转化为一维
var result = [
    {
        subject: 'math',
        score: 10
    },
    {
        subject: 'chinese',
        score: 20
    },
    {
        subject: 'english',
        score: 30
    }
];

var sum = result.reduce(function(prev, cur) {
    return cur.score + prev;
}, 0);
console.log(sum) //60
  • reduce求最大值
let arr = [1, 2, 3, 2, 4]
let max = arr.reduce(function(prev, cur) {
    return Math.max(prev, cur)
})
console.log(max)
  • reduce获取累加值
let arr = [1, 2, 3, 2, 4]
let sum = arr.reduce(function(prev, cur, index, array) {
    return prev + cur
}, 0)
console.log(sum)

注意
for...in不能用于遍历数组。
for...in代码块中不能有 return,不然会抛出异常
for...in 确实可以遍历数组,而且还支持 continue、break等功能,但是它真的没有瑕疵吗?如果 array 有自定义属性,你发现也会被遍历出来(显然不合理)。这是因为 for...in 是为遍历对象创造的({a:1, b:2}),不是为数组设计的。

ES6 中数组遍历方式 for...of

for (let val of [1, 2, 3]) {
    console.log(val);
}

for...of是支持 break、continue、return的,所以在功能上非常贴近原生的 for。

Array.from()

伪数组(Array-Like)不能直接使用数组API,比如函数中的 arguments、DOM中的 NodeList等。
要想对这些对象使用数组的 API 就要想办法把它们转化为数组。

let args = [].slice.call(arguments);
let imgs = [].slice.call(document.querySelectorAll('img'));

ES6伪数组(Array-Like)转化成数组

let args = Array.from(arguments);
let imgs = Array.from(document.querySelectorAll('img'));

伪数组具备两个特征,1. 按索引方式储存数据 2. 具有length属性;如:

let arrLike = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3
}

Array.from语法Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike 想要转换成数组的伪数组对象或可迭代对象 Y
mapFn 如果指定了该参数,新数组中的每个元素会执行该回调函数 N
thisArg 可选参数,执行回调函数 mapFn 时 this 对象 N

Array.from 还具备 map 的功能
比如想初始化一个长度为 5 的数组,每个数组元素默认为 1

let arr = Array(6).join(' ').split('').map(item => 1)
// [1,1,1,1,1]

用Array.from 实现初始化一个长度为 5 的数组,Array.from 初始化为一个长度固定,元素为指定值的数组。

Array.from({
    length: 5
}, function() {
    return 1
})
//[1, 1, 1, 1, 1]

Array.of()

Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型

  • Array.of(7) 创建一个具有单个元素 7 的数组
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
  • Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]

Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]

语法:Array.of(element0[, element1[, ...[, elementN]]])

Array.prototype.fill()

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引

语法:arr.fill(value[, start[, end]])
fill 不具备遍历的功能,它是通过指定要操作的索引范围来进行,通过这道题目可以看出不指定索引会对所有元素进行操作

参数 含义 必选
value 用来填充数组元素的值 Y
start 起始索引,默认值为0 N
end 终止索引,默认值为 this.length N

let array = [1, 2, 3, 4]

array.fill(0, 1, 2)
// [1,0,3,4]

这个操作是将 array 数组的第二个元素(索引为1)到第三个元素(索引为2)内的数填充为 0,不包括第三个元素,所以结果是 [1, 0, 3, 4]

  • fill初始化为一个长度固定,元素为指定值的数组
Array(5).fill(1)
// [1,1,1,1,1]

Array.prototype.find()

find() 方法返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。
语法:arr.find(callback[, thisArg])

参数 含义 必选
callback 在数组每一项上执行的函数,接收 3 个参数,element、index、array Y
thisArg 执行回调时用作 this 的对象 N
let array = [5, 12, 8, 130, 44];
let found = array.find(function(element) {
    return element > 10;
});
console.log(found);
// 12

Array.prototype.findIndex()

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。其实这个和 find() 是成对的,不同的是它返回的是索引而不是值。

语法:arr.findIndex(callback[, thisArg])

参数 含义 必选
callback 在数组每一项上执行的函数,接收 3 个参数,element、index、array Y
thisArg 执行回调时用作 this 的对象 N
let array = [5, 12, 8, 130, 44];
let found = array.find(function(element) {
    return element > 10;
});
console.log(found);
// 1

Array.prototype.copyWithin()

在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

语法:arr.copyWithin(target, start = 0, end = this.length)

参数 含义 必选
target 从该位置开始替换数据。如果为负值,表示倒数 Y
start 从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算 N
end 到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算 N
let arr = [1, 2, 3, 4, 5]
console.log(arr.copyWithin(1, 3))
// [1, 4, 5, 4, 5]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容