10. Array API

  1. 类数组对象,可迭代对象,数组之间的区别?
    • 类数组对象:

      格式与数组结构类似,用于length,可以通过索引来访问或者修改里面的元素,但不能书用数组的方法


类数组对可以通过Array.from()来转换成数组,需要有length属性来控制数组长度
注意:

  1. 1. 解析`length`时会使用`parseInt()`进行转换,默认为0
  2. 2. 如果`length`超过实际长度时,会用`undefined`填充,小于进行切片
  1. const array = {0: 'apple', 1: 'orange', 2: 'strawberry', length: 'string'};
  2. console.log(Array.from(array)); //[]
  • 可迭代对象

    Iterable是实现了 Symbol.iterator 方法的对象。


for..of循环认识它 :
为了让range对象可迭代,我们需要为对象添加一个名为Symlbol.iterator的方法

  1. 1. `for..of`循环启动时,它会调用这个方法(如果没有就会报错),这个方法必须返回一个**迭代器**<br />**(iterator)** ,这个迭代器拥有`next`方法
  2. 2. `for..of`循环希望取得下一个数值,它就调用这个对象的`next()`方法
  3. 3. `next()`方法必须返回格式为`{done:Boolean,value:any}`,当`done为true`时,表示循环结束,否则`value`是下一个值
  1. let range = {
  2. from: 1,
  3. to: 5,
  4. [Symbol.iterator]() {
  5. // 1.它返回迭代器对象(iterator object):
  6. // 2. 接下来,for..of 仅与下面的迭代器对象一起工作,要求它提供下一个值
  7. return {
  8. current: this.from,
  9. last: this.to,
  10. // 3. next() 在 for..of 的每一轮循环迭代中被调用
  11. next() {
  12. // 4. 它将会返回 {done:.., value :...} 格式的对象
  13. if(this.current <= this.last) {
  14. return {done: false,value:this.current++}
  15. }else {
  16. return {done:true};
  17. }
  18. }
  19. }
  20. }
  21. };
  22. for(let num of range) {
  23. console.log(num);
  24. }
  1. 罗列数组的常见方法
  • 静态方法
    1. new Array():创建数组的构造函数
    2. Array.from()参数为一个类数组对象,即任何可迭代的结构
    3. Array.of()可以把一组参数转化为数组,这个方法用于替代在ES6之前使用的Array.prototype.slice.call(arguments)
      1. console.log(Array.of(1,2,3,4)) // [1,2,3,4]
  1. Array.isArray()检测参数是否为一个数组
    • 搜索和位置方法
  2. 严格相等搜索 :

    • indexOf()
    • lastIndexOf()
    • includes()

      前两个方法在所有版本都可以使用,而第二个方法是es7新增的.这些方法都接受两个参数: 要查找的元素一个可选的起始搜索位置,lastIndexOf()从后面开始搜索

      indexOf()LastIndexOf()都要返回查找的元素在数组中的位置,如果没有找到就返回-1,includes()返回布尔值,表示是否能找到.每一项都会用(===)比较

  3. 断言函数搜索 :

    断言函数参数(element,index,array) => Boolean.

  1. - `find()` 返回满足搜索的第一个元素本身
  2. - `findIndex()` 返回满足搜索条件的第一个元素的索引
  1. const persons = [
  2. {name: 'alice', age: 18},
  3. {name: 'bob', age: 20},
  4. {name: 'jery', age: 19},
  5. ];
  6. const ageAbove19 = (person) => person.age > 19;
  7. const personFound = persons.find(ageAbove19);
  8. console.log(personFound);
  9. // { name: 'bob', age: 20 }
  10. const personIndexFound = persons.findIndex(ageAbove19);
  11. console.log(personIndexFound); //1
  • 操作方法

    1. concat()合并多个数组,原数组不变,Symbol.isConcatSpreadable可以阻止其打平参数数组
    2. slice()参数:(start,end) end不写默认到结尾,截取数组
    3. splice()主要目的是在数组中插入元素,但有三种用法

      • 删除 :两个参数:要删除的第一个元素的位置和要删除的数量 splice(0,2)可以删除前两个元素
      • 插入:三个参数:开始位置,删除的数量,要插入的元素.比如splice(2,0,'red','green')会在位置2插入字符串red green
      • 替换: 通用传入三个元素.根据插入的用法删除一个元素替换掉
        应用:
        1. //insert
        2. Array.prototype.insert = function insert(index, ...items) {
        3. this.splice(index, 0, ...items);
        4. return this;
        5. };
        6. //update
        7. Array.prototype.update = function update(index, ...items) {
        8. this.splice(index, 1, ...items);
        9. return this;
        10. };
        11. //remove
        12. Array.prototype.remove = function remove(index, removeCount) {
        13. this.splice(index, removeCount);
        14. return this;
        15. };
    4. push() 该方法返回被弹出的元素

    5. pop()取出第一个元素,返回被取出的元素
    6. shift()向数组开头添加批量的元素。返回改变后的数组长度。
  • 迭代器方法
    1. keys()返回数组索引的迭代器
    2. values()返回数组元素的迭代器
    3. entries()返回索引/值对的迭代器 ```javascript const colors = [‘red’,’blue’,’green’];

const Keys = Array.from(colors.keys()); const Values = Array.from(colors.values()); const Entries = Array.from(colors.entries());

console.log(Keys); //[ 0, 1, 2 ] console.log(Values); //[ ‘red’, ‘blue’, ‘green’ ] console.log(Entries); // [ [ 0, ‘red’ ], [ 1, ‘blue’ ], [ 2, ‘green’ ] ]

  1. 补充 : 在遍历`entries`时可以通过`ES6`的解构
  2. - 迭代方法
  3. 1. `forEach() :` 对数组每一项都运行传入的函数,没有返回值.不允许中途 break 或者 continue
  4. ```javascript
  5. let array = [1,2,3];
  6. array.forEach((item) => {
  7. item += 10;
  8. })
  9. console.log(array); // [ 1, 2, 3 ]


注意 :

  1. - `forEach()`不能改变原数组
  2. - `break 和 continue`都可以通过`return`实现
  1. map() : 对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组 ```javascript let array = [1,2,3];

let ans = array.map((item) => { return item + 10; })

console.log(ans);

  1. <br />**注意 :** 需要有**返回值**
  2. 3. `fiter() :` 检查每个元素是否满足过滤条件,返回满足过滤条件的数组
  3. ```javascript
  4. const colors = ['red','blue','green'];
  5. console.log(colors.filter((item) => item.length > 3)); //[ 'blue', 'green' ]
  1. every() :对每一项都运行传入的函数,如果对每一项函数都返回true,这这个方法返回true ```javascript //1 const nums = [1, 2, 3];

const isAllNumber = nums.every((num) => typeof num === ‘number’);

console.log(isAllNumber); // true //2 const nums = [1, 2, 3, ‘4’];

const isAllNumber = nums.every((num) => typeof num === ‘number’);

console.log(isAllNumber); //false

  1. 5. `some() :`只要有满足条件的就返回`true`
  2. 6. `reduce() :`逐个遍历数组元素,每一步都将当前元素的值与上一步的计算结果相加(上一步的计算结果是当前元素之前所有元素的总和)——直到没有更多的元素被相加。
  3. ```javascript
  4. const arr = [1,2,3,4];
  5. const ans = arr.reduce((pre,cur) => pre+cur);
  6. console.log(ans); //10


数组扁平化:

  • 顺序相关方法
    1. sort()
    2. reverse()

注意:

  1. `reverse()``sort()`都返回调用它们的数组的引用
  1. 实现 deepFlat
    • **reduce方法** ```javascript const { log } = console;

const arr = [1, [2], [3, [4]], [[[6]]]];

log(arr.flat());

function deepFlat(arr) { return arr.reduce((res,next) => { return res.concat(Array.isArray(next) ? deepFlat(next) : next); },[]) }

log(deepFlat(arr));

  1. - `Es6新方法 : Array.prototype.flat()`
  2. ```javascript
  3. let a = [1,[2,3]];
  4. a.flat(); // [1,2,3]
  5. a.flat(1); //[1,2,3]
  6. let a = [1,[2,3,[4,[5]]]];
  7. a.flat(3); // [1,2,3,4,5] a是4维数组
  8. // 若不知道数组维度进行扁平化,可直接使用Infinity,可对任意纬度数组进行扁平化
  9. let a = [1,[2,3,[4,[5]]]];
  10. a.flat(Infinity); // [1,2,3,4,5] a是4维数组
  11. // 若不知道数组维度进行扁平化,可直接使用Infinity,可对任意纬度数组进行扁平化
  • 循环 ```javascript const { log } = console;

const arr = [1, [2], [3, [4]], [[[6]]]];

log(arr.flat());

function deepFlat(arr) { let res = []; for(let i = 0 , length = arr.length ; i < length ; i ++) { if(Array.isArray(arr[i])) { res.push(…deepFlat(arr[i])) } else res.push(arr[i]); } return res; }

log(deepFlat(arr));

  1. 4. 实现 reduce 方法
  2. ```javascript
  3. const { log } = console;
  4. function myReduce(arr, reducer, initialValue) {
  5. let res = initialValue || arr[0];
  6. let startIndex = initialValue ? 0 : 1;
  7. for(let i = startIndex ; i < arr.length; i ++) {
  8. res = reducer(res,arr[i]);
  9. }
  10. return res;
  11. }
  12. log(myReduce([1, 2, 3], (pre, cur) => pre + cur, 10));
  1. 实现 shuffle 方法
    1. sort() ```javascript const { log } = console;

Array.prototype.shuffle = function() { return this.sort(function(a, b) { return Math.random() > 0.5 ? -1:1 }); }

const nums = [1, 2, 3, 4, 5]; log(nums.shuffle());

  1. 2. `Math.random`
  2. ```javascript
  3. Array.prototype.shuffle = function () {
  4. const len = this.length;
  5. for (let i = len - 1; i > 0; i--) {
  6. const j = ~~(Math.random() * (i + 1));
  7. [this[i], this[j]] = [this[j], this[i]];
  8. }
  9. return this;
  10. };