创建数组

Array构造函数

不要求必须带 new 关键字,不带时会自动补上

  1. var arr1 = new Array(); //创建一个空数组
  2. var arr2 = new Array(20); // 创建一个包含20项的数组
  3. var arr3 = new Array("lily","lucy","Tom"); // 创建一个包含3个字符串的数组
  4. var arr4 = Array(1000).fill(0) // 创一个1000个0的数组

字面量

  1. var arr4 = []; //创建一个空数组
  2. var arr5 = [20]; // 创建一个包含1项数据为20的数组
  3. var arr6 = ["lily","lucy","Tom"]; // 创建一个包含3个字符串的数组


Array 构造函数还有两个ES6新增的用于创建数组的静态方法:from() 和 of() 。
from() 用于将类数组结构转换为数组实例,而of() 用于将一组参数转换为数组实例。

  • 创建二维数组 ```javascript const arrayNumbers = Array.from(Array(2), () => new Array(4));

const arrayNumbers = Array(2) .fill() .map(() => Array(4));

  1. <a name="yS3am"></a>
  2. ### Array.from()
  3. Array.from() 的第一个参数是一个类数组对象,即任何可迭代的结构,或者有一个length 属性和可索引元素的结构.。这个方法用于替代在ES6之前常用的`Array.prototype.slice.call(arguments) `
  4. > 典型的“类似数组的对象”是**函数的arguments对象,以及大多数 DOM 元素集,还有字符串。只要是部署了iterator接口的数据结构,Array.from都能将其转为数组**
  5. ```javascript
  6. // 所谓类似数组的对象,本质特征只有一点,即必须有length属性。
  7. // 因此,任何有length属性的>对象,都可以通过Array.from方法转为数组
  8. Array.from({length: 5}) // [undefined, undefined, undefined, undefined, undefined]
  9. // 字符串会被拆分为单字符数组
  10. console.log(Array.from("Matt")); // ["M", "a", "t","t"]
  11. // arguments对象可以被轻松地转换为数组
  12. function getArgsArray() {
  13. return Array.from(arguments);
  14. }
  15. console.log(getArgsArray(1, 2, 3, 4)); // [1, 2, 3,4]

Array.from() 还接收第二个可选的映射函数参数。这个函数可以直接增强新数组的值,而无须像调用Array.from().map() 那样先创建一个中间数组。还可以接收第三个可选参数,用于指定映射函数中this 的值。但这个重写的this 值在箭头函数中不适用。

  1. const a1 = [1, 2, 3, 4];
  2. const a2 = Array.from(a1, x => x**2);
  3. console.log(a2); // [1, 4, 9, 16]

Array.of()

Array.of() 可以把一组参数转换为数组。

Array.of()Array 构造函数之间的区别在于处理整数参数:Array.of(2) 创建一个具有单个元素 2 的数组,而 Array(2) 创建一个长度为2的空数组

  1. let items = new Array(2) ;
  2. console.log(items.length) ; // 2
  3. items = Array.of(2);
  4. console.log(items.length); // 1

Array.isArray()

使用instanceof的问题是假定只有一个全局执行上下文。如果网页里有多个框架,则可能涉及两个不同的全局执行上下文,因此就会有两个不同版本的 Array 构造函数。如果要把数组从一个框架传给另一个框架,则这个数组的构造函数将有别于在第二个框架内本地创建的数组。

为解决这个问题,ECMAScript提供了 Array.isArray() 方法。这个方法的目的就是确定一个值是否为数组,而不用管它是在哪个全局执行上下文中创建的。

数组的空位

  1. Array(3) // [, , ,] 注意,空位不是undefined

ES5 对空位的处理,已经很不一致了,大多数情况下会忽略空位。

  • forEach(), filter(), reduce(), every() 和some()都会跳过空位。
  • map()会跳过空位,但会保留这个值
  • join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。
  • Array.from()方法会将数组的空位,转为undefined,也就是说,这个方法不会忽略空位。
  • 扩展运算符(…)也会将空位转为undefined。
  • copyWithin()会连空位一起拷贝。
  • fill()会将空位视为正常的数组位置。for…of循环也会遍历空位。
  • entries()、keys()、values()、find()和findIndex()会将空位处理成undefined ```javascript Array.apply(null, {length: 10}) Array.apply(null, Array(10)) Array.apply(null, new Array(10))

// 这三个方法相当于 Array(undefined, undefined, undefined, …)

// 其他写法 Array.from({length: 10}) Array(…Array(10))

  1. <a name="b6FaX"></a>
  2. ## 常用方法
  3. <a name="nD8DP"></a>
  4. ### 队列方法
  5. - shift() :
  6. - unshift():
  7. <a name="bsJ2b"></a>
  8. ### 栈方法
  9. - push() :
  10. - pop():
  11. ```javascript
  12. //删除数组最前面(头部)的元素
  13. let first = fruits.shift();
  14. //添加元素到数组的头部
  15. let newLength = fruits.unshift('Strawberry')
  16. //添加元素到数组的末尾
  17. let newLength = fruits.push('Orange');
  18. //删除数组末尾的元素
  19. let last = fruits.pop();

搜索和位置方法

严格相等
indexOf() :从数组前头(第一项)开始向后搜索
lastIndexOf(): 从数组末尾(最后一项)开始向前搜索

  • 都返回要查找的元素在数组中的位置,如果没找到则返回-1。

includes()

  • 返回布尔值,表示是否至少找到一个与指定元素匹配的项。
    1. let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
    2. alert(numbers.indexOf(4)); // 3
    3. alert(numbers.lastIndexOf(4)); // 5
    4. alert(numbers.includes(4)); // true

断言函数
find() : 返回第一个匹配的元素
findIndex(): 返回第一个匹配元素的索引

find()与 findIndex()方法均接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的 this。

该回调函数可接受三个参数:数组的某个元素,该元素对应的索引位置,以及该数组本身。

该回调函数应当在给定的元素满足你定义的条件时返回 true,而 find()和 findIndex()方法均会在回调函数第一次返回 true 时停止查找。
二者的区别是:find()方法返回匹配的值,而 findIndex()返回匹配位置的索引。

  1. const array = [5, 12, 8, 130, 44];
  2. const found = array.find(e => e > 10);
  3. console.log(found);//12


排序算法

reverse() :

  1. let values = [1, 2, 3, 4, 5];
  2. values.reverse();
  3. alert(values); // 5,4,3,2,1

sort() :

  1. let values = [0, 1, 5, 10, 15];
  2. function compare(a, b){
  3. return a - b;
  4. }
  5. values.sort(compare);
  6. alert(values); // 0,1,5,10,15

迭代器方法

  • keys() 返回数组索引的迭代器
  • values() 返回数组元素的迭代器
  • entries() 返回索引/值对的迭代器

都返回一个新的Array Iterator对象

  1. const a = ["foo", "bar", "baz", "qux"];
  2. // 通过Array.from()直接转换为数组实例
  3. const aKeys = Array.from(a.keys());
  4. const aValues = Array.from(a.values());
  5. const aEntries = Array.from(a.entries());
  6. console.log(aKeys); // [0, 1, 2, 3]
  7. console.log(aValues); // ["foo", "bar", "baz", "qux"]
  8. console.log(aEntries); // [[0, "foo"], [1, "bar"],[2, "baz"], [3, "qux"]]
  9. // 使用ES6的解构可以非常容易地在循环中拆分键/值对:
  10. for (const [idx, element] of a.entries()) {
  11. alert(idx);
  12. alert(element);
  13. }

复制和填充方法

  • fill(value,start,end)
  • copyWithin(target.start,end) 浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度 ```javascript const zeroes = [0, 0, 0, 0, 0]; // 用7填充索引大于等于1且小于3的元素 zeroes.fill(7, 1, 3); // 用6填充索引大于等于3的元素 zeroes.fill(6, 3); // 用5填充整个数组 zeroes.fill(5);

const ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // 从ints中复制索引0开始的内容,插入到索引5开始的位置 // 在源索引或目标索引到达数组边界时停止 ints.copyWithin(5);

// 从ints中复制索引5开始的内容,插入到索引0开始的位置 ints.copyWithin(0, 5);

// 从ints中复制索引0开始到索引3结束的内容,插入到索引4开始的位置 ints.copyWithin(4, 0, 3);

  1. <a name="ekI1R"></a>
  2. ### 转换方法
  3. - valueOf()
  4. - toString()
  5. - toLocaleString()
  6. valueOf() 返回的还是数组本身。而toString() 返回由数组中每个值的等效字符串拼接而成的一个逗号分<br />隔的字符串。也就是说,对数组的每个值都会调用其toString() 方法,以得到最终的字符串。
  7. ```javascript
  8. let colors = ["red", "blue", "green"]; // 创建一个包含3个字符串的数组
  9. alert(colors.toString()); // red,blue,green
  10. alert(colors.valueOf()); // red,blue,green
  11. alert(colors); // red,blue,green
  12. 首先是被显式调用的 toString() 和 valueOf() 方法,
  13. 它们分别返回了数组的字符串表示,即将所有字符串组合起来,以逗号分隔。
  14. 最后一行代码直接用 alert() 显示数组,因为 alert() 期待字符串,
  15. 所以会在后台调用数组的 toString() 方法,从而得到跟前面一样的结果。

toLocaleString() 方法也可能返回跟 toString() 和 valueOf() 相同的结果,但也不一定。它与另外两个方法唯一的区别是,为了得到最终的字符串,会调用数组每个值的 toLocaleString() 方法,而不是 toString() 方法。

继承的方法 toLocaleString() 以及 toString() 都返回数组值的逗号分隔的字符串。如果想使用不同的分隔符,则可以使用 join() 方法。 join() 方法接收一个参数,即字符串分隔符。

  1. let colors = ["red", "green", "blue"];
  2. alert(colors.join("||")); // red||green||blue

如果数组中某一项是 null 或 undefined ,则在 join() 、toLocaleString() 、toString() 和 valueOf() 返回的结果中会以空字符串表示。

操作方法

  • concat():

    • 如果传入一个或多个数组,则 concat() 会把这些数组的每一项
    • 都添加到结果数组。如果参数不是数组,则直接把它们添加到结果数组末尾。
      1. let colors = ["red", "green", "blue"];
      2. let colors2 = colors.concat("yellow", ["black","brown"]);
      3. console.log(colors); // ["red", "green","blue"]
      4. console.log(colors2); // ["red",
  • slice(begin,end) :

    • 如果只有一个参数,则 slice() 会返回该索引到数组末尾的所有元素。
    • 如果有两个参数,则 slice() 返回从开始索引到结束索引对应的所有元素,其中不包含结束索引对应的元素。
    • 如果 slice() 的参数有负值,那么就以数值长度加上这个负值的结果确定位置。
    • 记住,这个操作不影响原始数组。
      1. let colors = ["red", "green", "blue", "yellow","purple"];
      2. let colors2 = colors.slice(1);
      3. let colors3 = colors.slice(1, 4);
      4. alert(colors2); // green,blue,yellow,purple
      5. alert(colors3); // green,blue,yellow
  • splice(start,delCount,item1,item2….) :开始位置、要删除的元素数量、要插入的元素

    • 删除。需要给 splice() 传2个参数:要删除的第一个元素的位置和要删除的元素数量。可以从数组中删除任意多个元素,比如splice(0, 2) 会删除前两个元素。
    • 插入。需要给 splice() 传3个参数:开始位置、0(要删除的元素数量)和要插入的元素,可以在数组中指定的位置插入元素。第三个参数之后还可以传第四个、第五个参数,乃至任意多个要插入的元素。比如, splice(2, 0, “red”, “green”) 会从数组位置2开始插入字符串 “red” 和 “green” 。
    • 替换。 splice() 在删除元素的同时可以在指定位置插入新元素,同样要传入3个参数:开始位置、要删除元素的数量和要插入的任意多个元素。要插入的元素数量不一定跟删除的元素数量一致。比如,splice(2, 1, “red”, “green”) 会在位置2删除一个元素,然后从该位置开始向数组中插入 “red” 和 “green”
      ```javascript let colors = [“red”, “green”, “blue”]; let removed = colors.splice(0,1); // 删除第一项 alert(colors); // green,blue alert(removed); // red,只有一个元素的数组

removed = colors.splice(1, 0, “yellow”, “orange”);// 在位置1插入两个元素 alert(colors);// green,yellow,orange,blue alert(removed);// 空数组

removed = colors.splice(1, 1, “red”, “purple”); //插入两个值,删除一个元素 alert(colors); //green,red,purple,orange,blue alert(removed); //yellow,只有一个元素的数组

  1. <a name="4C8k9"></a>
  2. ####
  3. <a name="p3YR6"></a>
  4. #### 迭代方法
  5. **这些方法都不改变调用它们的数组。**
  6. ```javascript
  7. (function(currentValue,index,arr), thisArg)
  8. -currentValue 必须。当前元素的值
  9. -index 可选。当前元素的索引值
  10. -arr 可选。当前元素属于的数组对象
  11. -thisArg 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
  12. 如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。

注意:如果使用箭头函数表达式来传入函数参数, thisArg 参数会被忽略,因为箭头函数在词法上绑定了 this 值

  • forEach() :对数组每一项都运行传入的函数没有返回值
  • map() :对数组每一项都运行传入的函数返回由每次函数调用的结果构成的数组
    • 只是遍历元素则可用forEach。
    • 需要根据原数组得到新的数组使用map。
  • filter() :对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回。

这个方法非常适合从数组中筛选满足给定条件的元素

  1. const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
  2. const filterItems = (query) =>
  3. fruits.filter((el) =>
  4. el.toLowerCase().indexOf(query.toLowerCase()) > -1
  5. );
  6. console.log(filterItems('ap')); // ['apple', 'grapes']
  • every() :对数组每一项都运行传入的函数,如果对每一项函数都返回 true ,则这个方法返回 true 。
  • some() :对数组每一项都运行传入的函数,如果有一项函数返回true ,则这个方法返回 true 。

归并方法

  • reduce(callback(accumulator, currentValue, index, array), initialValue)
  • reduceRight()

这两个方法都会迭代数组的所有项,并在此基础上构建一个最终返回值。 reduce() 方法从数组第一项开始遍历到最后一项。而 reduceRight() 从最后一项开始遍历至第一项。

函数接收4个参数:上一个归并值、当前项、当前项的索引和数组本身。

调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。

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

  1. let values = [1, 2, 3, 4, 5];
  2. let sum = values.reduce((prev, cur, index, array) => prev + cur);
  3. alert(sum); // 15