【JavaScript】 数组 Array

1 数组

js 数组
es 数组


数组属于一种特殊的对象,键名就是整数 0、1、2。

  • 除了在定义时赋值,数组也可以先定义后赋值。
  • 如果数组的元素还是数组,就形成了多维数组。
var a = [
  [1, 2],
  [3, 4],
];
a[0][1]; // 2
a[1][1]; // 4

1.1 数组成员

1.1.1 属性

  • length,返回数组的成员数量。是数组本身独有的属性

  • 清空数组的一个有效方法,就是将length属性设为 0。

  • length 不是计算数组属性的长度,length 是计算数组下标最大的值+1

  • 对象没有 length 属性,对象不能用 length 返回其拥有的属性对象

  • 按照数组添加成员,数组本身更新

  • 按照对象添加成员,不会触发数组的更新

1.1.2 delete

  • 使用delete命令删除一个数组成员,会形成空位,并且不会影响length属性。
var a = [1, 2, 3];
delete a[1];

a[1]; // undefined
a.length; // 3
  • 上面代码用delete命令删除了数组的第二个元素,这个位置就形成了空位,但是对length属性没有影响。也就是说,length属性不过滤空位。所以,使用length属性进行数组遍历,一定要非常小心。
  • 数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。
  • 这就是说,空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。
  • 如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。
var obj = {
  0: "a",
  1: "b",
  2: "c",
  length: 3,
};

1.1.3 in 运算符

  • 检查某个键名是否存在,适用于对象,也适用于数组。
var arr = ["a", "b", "c"];
2 in arr; // true
"2" in arr; // true
4 in arr; // false

1.2 类似数组的对象

  • 典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串。
  • 数组的slice方法可以将“类似数组的对象”变成真正的数组。
var arr = Array.prototype.slice.call(arrayLike);
  • 除了转为真正的数组,“类似数组的对象”还有一个办法可以使用数组的方法,就是通过call()把数组的方法放到对象上面。
function print(value, index) {
  console.log(index + " : " + value);
}

Array.prototype.forEach.call(arrayLike, print);

1.3 数组遍历

1.3.1 for 循环

var a = [1, 2, 3];

for (var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

1.3.2 for…in 循环

  • 注意:for…in 循环非常不建议用在数组上,for…in 是为遍历对象属性而构建的,当然数组也可以用。
  • for…in 语句以任意顺序遍历一个对象的除 Symbol 以外的可枚举属性 。
var a = [1, 2, 3];

for (var i in a) {
  console.log(a[i]);
}

1.3.3 while 循环

var a = [1, 2, 3];

// while循环
var i = 0;
while (i < a.length) {
  console.log(a[i]);
  i++;
}

// 逆向遍历,即从最后一个元素向第一个元素遍历
var l = a.length;
while (l--) {
  console.log(a[l]);
}

1.3.4 for…of 循环

  • for…of 语句在 可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句 。
  • for of 循环是 ES6 的新增方法,针对 for in 循环的 bug,for of 循环就不会有问题:
const arr:any = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.name = 12;

for(const item of arr) {
    console.log(item)
}

# 输出结果:
# 1 2 3 4 5 6 7 8 9

1.3.5 forEach 循环

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
forEach()方法不返回值,只用来操作数据

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

arr.forEach((item, index, arr) => {
    console.log(item)
});

# 输出结果:
# 1 2 3 4 5 6 7 8 9

1.3.6 map 循环

map 循环返回一个经过调用函数处理后的新的数组

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const res = arr.map((item,index,arr)=>{
    return item + 1
})
console.log(res)

// [2, 3, 4, 5, 6, 7, 8, 9, 10]
  • map 循环不会对空数组进行检测 。
  • map 循环必须 return 。
  • map 循环不会修改原数组。
  • map 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
  • map 循环会针对每一项都进行循环,如果跳过则会返回 undefined,

1.3.7 filter 循环

filter() 循环返回一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const res = arr.filter((item,index,arr)=>{
    return item > 3;
});
console.log(res)

// [4, 5, 6, 7, 8, 9]
  • filter 循环不会对空数组进行检测。
  • filter 循环不会改变原数组。
  • filter 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

1.3.8 some 循环

  • some 循环查找数组中任意符合条件的元素并返回 boolean 值,当数组中有任意元素符合条件就返回 true 否则返回 fasle
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const res = arr.some((item,index,arr)=>{
    return item > 3
})
console.log(res)
// true
  • some 循环会依次执行数组的每一个元素。
  • 如果有一个元素满足条件,则返回 true,且剩余的元素不会在执行检测 即 循环结束。
  • some 循环不会对空数组进行检测
  • some 循环不会改变原数组
  • some 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

1.3.9 every 循环

every 循环查找数组中所有符合条件的元素并返回 boolean 值,只有当数组中有所有元素都符合条件才返回 true 否则返回 fasle

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const res = arr.every((item,index,arr)=>{
    return item > 3
})
console.log(res);

// false
  • every 循环会检测数组的每一个元素
  • 如果有一个元素不满足条件,则返回 false,且剩余元素不在检测 即 循环结束。
  • every 循环不会对空数组进行检测
  • every 循环不会改变原数组。
  • every 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

1.3.10 reduce 循环

reduce() 循环接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const res = arr.reduce((total,item,index,arr)=>{
    return total + item;
}, 0)
console.log(res)// 45
  • reduce 循环对于空数组是不会执行回调函数的。
  • reduce 循环接受一个回调函数,和一个初始值。
  • 回调函数接受四个参数:[第一参数]为数组中的每一项累加和,[第二参数]为数组的每一项,[第三个参数]为数组的下标,[第四个参数]为你要遍历的数组本身。第三和第四参数都是可选的。
  • 初始值,即为指定第一次循环时,累加参数[total] 的值。
  • 例如 demo 中,指定初始值为 0,则 reduce 循环的状态为:

[total + item]
0
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6

36 + 9 = 45

reduce 可以作为一个高阶函数,用于函数的 compose。

当然 reduce 的作用也不单单只作为一个累加器来用,我们还可以利用 reduce 的特性做其他的用途,比如数组的去重

1.4 扩展运算符

console.log(...[1, 2, 3])
// 1 2 3
  • 数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

  • 修改原数组,会直接导致复制的数组的变化。

  • 克隆数组:const arr = [...arr1]

  • 合并数组:const arr = [...arr1, ...arr2] 注意是浅拷贝

  • 拼接数组:arr.push(...arr1)

  • 代替 apply:Math.max.apply(null, [x, y]) => Math.max(...[x, y])

  • 转换字符串为数组:[..."hello"]

  • 转换类数组对象为数组:[...Arguments, ...NodeList]

  • 转换可遍历对象为数组:[...String, ...Set, ...Map, ...Generator]

  • 与数组解构赋值结合:const [x, ...rest] = [1, 2, 3] // // x == 1 // rest == [2, 3]

  • 计算 Unicode 字符长度:Array.from("hello").length => [..."hello"].length

1.5 Array 对象

Array 对象

1.5.1 Array()

  • 构造函数 var arr = new Array(2);var arr = Array(2);
  • Array()作为构造函数,行为很不一致,不建议使用它生成新数组,最好直接使用数组字面量。

1.5.2 Array 静态方法

  • Array.isArray() 方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof运算符的不足。

  • Array.from():转换具有 Iterator 接口的数据结构为真正数组,返回新数组

    • 类数组对象:包含 length 的对象、Arguments 对象、NodeList 对象
    • 可遍历对象:String、Set 结构、Map 结构、Generator 函数
  • Array.of():转换一组值为真正数组,返回新数组

1.5.3 Array 实例方法

1. 原数组

  • Array.prototype.valueOf() 所有对象都拥有的方法,表示对该对象求值。返回数组本身。
  • Array.prototype.toString() 所有对象都拥有的方法,返回数组的字符串形式。
var arr = [1, 2, 3];
arr.toString() // "1,2,3"

var arr = [1, 2, 3, [4, 5, 6]];
arr.toString() // "1,2,3,4,5,6"

2. 修改原数组

  • Array.prototype.push() 数组末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

  • Array.prototype.unshift() 数组第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

  • Array.prototype.shift() 删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。

  • Array.prototype.pop() 删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组。

    • push()pop()结合使用,就构成了“后进先出”的栈结构(stack)。
    • push()shift()结合使用,就构成了“先进先出”的队列结构(queue)。
  • Array.prototype.splice() 删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。

  • Array.prototype.sort() 对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。

  • Array.prototype.reverse() 颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组。

  • Array.prototype.copyWithin():在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。会修改当前数组。

  • Array.prototype.fill():根据指定值填充整个数组,返回原数组

3. 返回新变量

  • Array.prototype.join() 以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔。

  • Array.prototype.concat() 多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。

  • Array.prototype.slice() 提取目标数组的一部分,返回一个新数组,原数组不变。

  • Array.prototype.indexOf() 返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1

  • Array.prototype.lastIndexOf() 返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1

  • Array.prototype.map() 将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。

  • Array.prototype.forEach() 也是对数组的所有成员依次执行参数函数。但是,forEach()方法不返回值,只用来操作数据。

    • 这就是说,如果数组遍历的目的是为了得到返回值,那么使用map()方法,否则使用forEach()方法。
  • Array.prototype.filter() 用于过滤数组成员,满足条件的成员组成一个新数组返回。

  • Array.prototype.some() 接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值,表示判断数组成员是否符合某种条件

    • 只要一个成员的返回值是true,则整个some方法的返回值就是true,否则返回false
  • Array.prototype.every() 接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值,表示判断数组成员是否符合某种条件

    • 所有成员的返回值都是true,整个every方法才返回true,否则返回false
  • Array.prototype.find():找出第一个符合条件的数组成员,返回该成员,如果没有符合条件的成员,则返回undefined

  • Array.prototype.findIndex():返回第一个符合条件的成员索引值

  • Array.prototype.keys():返回以索引值为遍历器的对象

  • Array.prototype.values():返回以属性值为遍历器的对象

  • Array.prototype.entries():返回以索引值和属性值为遍历器的对象

    • 数组空位:ES6 明确将数组空位转为 undefined(空位处理规不一,建议避免出现)
  • Array.prototype.reduce() 依次处理数组的每个成员,最终累计为一个,从左到右处理

  • Array.prototype.reduceRight() 依次处理数组的每个成员,最终累计为一个,从右到左

    1. 累积变量。第一次执行时,默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
    2. 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
    3. 当前位置。一个整数,表示第二个参数(当前变量)的位置,默认为1
    4. 原数组。

这四个参数之中,只有前两个是必须的,后两个则是可选的。

[1, 2, 3, 4, 5].reduce(function (
  a,   // 累积变量,必须
  b,   // 当前变量,必须
  i,   // 当前位置,可选
  arr  // 原数组,可选
) {
  // ... ...
[1, 2, 3, 4, 5].reduce(function (a, b) {
  console.log(a, b);
  return a + b;
})
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15

1.6 应用

  • 数组添加元素:
    • 数组添加元素: array1.push(x, y) 把元素 x 和 y 添加到 array1 中
    • 合并数组: array1.push(...array2) 把数组 array2 的元素依次添加到 array1 中
  • 数组去重: Array.from(new Set(array1)) 对数组 array1 去重,返回一个新数组
  • 数组过滤:
    • array1.filter((item) => item) 对数组 array1 过滤,返回一个新数组,保留非空的
    • array1.filter((x) => { return x > 3 }) 对数组 array1 过滤,返回一个新数组,保留 > 3 的
  • 数组删除某些元素: array1.splice(idx, 1); 删除数组下标为 idx 的元素
  • 数组循环: array1.forEach((item) => { xxxxxx }) 对数组 array1 进行循环
  • 对象数组取值:
    • array.map((item) => { return item.path }) 取对象数组的某一值
    • array.map((v) => { return {...v, xxx: y} }) 取对象数组的某些值
    • array.map((v) => {return { ...v, oe: (v.oe as string).replace(/\;/g, ',') };}); 把对象数组的某个属性的值替换掉
  • 数组包含某些元素:

有时 array1 的 length = 0 ,但是 array1 ? true : false; 仍为 true
空数组[]和空对象{}对应的布尔值,都是 true。所以有时不能只判断 array1 是否为空,还要判断 array1.length
看返回的是什么,有没有在 长度为 0 的时候就 return 掉 if (result.total < 1) { return; }

JS 数组
数组的去重,截取,转字符串 - js 篇
js 中的循环(全)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值