js中的数组方法

6.2.1创建数组

  1. 构造函数

    可以省略new关键字

    let colors = new Array();
    console.log(colors);//[]
    
    // 传入数组的长度值
    let colors1 = new Array(20);
    console.log(colors1); //[ <20 empty items> ]
    
    // 传入要保存的元素
    let colors2 = new Array("red", "blue", "green");
    console.log(colors2); //[ 'red', 'blue', 'green' ]
    
  2. 数组字面量(不会调用Array构造函数)

    中括号中包含以逗号分隔的元素列表

    let colors3 = ["red", "blue", "green"];
    console.log(colors3); //[ 'red', 'blue', 'green' ]
    
    let names = [];
    console.log(names); //[]
    
    let values = [1, 2];
    console.log(values); //[ 1, 2 ]
    
  3. ES6新增(静态方法):from()

    第一个参数:一个类数组对象,即任何可迭代的结构,或者有一个length属性和可索引元素的结构。

    // 将映射转换为一个数组
    const m = new Map().set(1, 2).set(3, 4);
    console.log(m); //Map { 1 => 2, 3 => 4 }
    console.log(Array.from(m)); //[ [ 1, 2 ], [ 3, 4 ] ]
    
    // 将集合转换为一个数组
    const s = new Set().add(1).add(2).add(3).add(4);
    console.log(s); //Set { 1, 2, 3, 4 }
    console.log(Array.from(s)); //[ 1, 2, 3, 4 ]
    
    // 对现有数组执行浅复制
    const a1 = [1, 2, 3, 4];
    const a2 = Array.from(a1);
    console.log(a2); // [ 1, 2, 3, 4 ]
    console.log(a1 === a2); // false
    
    // 可以使用任何可迭代对象
    const iter = {
      *[Symbol.iterator]() {
        yield 1;
        yield 2;
        yield 3;
        yield 4;
      }
    }
    console.log(iter); //{ [Symbol(Symbol.iterator)]: [GeneratorFunction: [Symbol.iterator]] }
    console.log(Array.from(iter)); // [ 1, 2, 3, 4 ]
    
    // 转换arguments对象
    function getArgsArray() {
      return Array.from(arguments);
    }
    console.log(getArgsArray(1, 2, 3, 4)); // [ 1, 2, 3, 4 ]
    
    // 转换带有必要属性的自定义对象
    const arrayLikeObject = {
      0: 1,
      1: 2,
      2: 3,
      3: 4,
      length: 4
    }
    console.log(Array.from(arrayLikeObject)); // [ 1, 2, 3, 4 ]
    

    第二个参数:可选的映射函数参数,这个函数可以直接增强新数组的值,而无须像调用Array.from.map()那样先创建一个中间数组。

    第三个参数:指定映射函数中this的值,但这个重写的this值在箭头函数中不适用。

    const a1 = [1, 2, 3, 4];
    const a2 = Array.from(a1, x => x ** 2);
    const a3 = Array.from(a1,function(x){return x**this.exponent},{exponent:2})
    console.log(a2); // [ 1, 4, 9, 16 ]
    console.log(a3); // [ 1, 4, 9, 16 ]
    console.log(3 * 2); //代表3乘以2得6
    console.log(3 ** 2); //代表3的平方得9
    
  4. ES6新增(静态方法):of()

    可以把一组参数转换为数组,用于代替在ES6之前使用的Array.prototype.slice.call(arguments)写法

    console.log(Array.of(1, 2, 3, 4)); // [ 1, 2, 3, 4 ]
    console.log(Array.of(undefined)); // [ undefined ]
    

6.2.2数组空位

使用数组字面量创建数组时,可以使用一串逗号来创建空位(hole)。

  1. ECMAScript会将逗号之间相应索引位值的值当成空位。

    const options = [, , , , ,];
    console.log(options.length); // 5
    console.log(options); // [ <5 empty items> ]
    
    const options = [1, , , , 5];
    for (const option of options) {
      console.log(option === undefined);
    }
    // false
    // true
    // true
    // true
    // false
    
    
  2. ES6新增方法普遍将这些空位当成存在的元素,只不过值是undefined

    const a = Array.from([, , ,]);
    for (const val of a) {
      console.log(val === undefined);
    }
    // true
    // true
    // true
    
    console.log(Array.of(...[, , ,])); // [ undefined, undefined, undefined ]
    
    for (const [index, value] of options.entries()) {
      console.log(value);
    }
    // 1
    // undefined
    // undefined
    // undefined
    // 5
    
  3. ES6之前的方法则会忽略这个空位。

    const options = [1, , , , 5];
    // map()会跳过空位置
    console.log(options.map(() => 6)); //[ 6, <3 empty items>, 6 ]
    // join()视空位置为空字符串
    console.log(options.join('-')); // 1----5
    

6.2.3数组索引

  1. 要取得或设置数组的值,需要使用中括号并提供相应值的数字索引

    let colors = ["red", "blue", "green"];// 索引小于数组长度,返回存储在相应位置的元素console.log(colors[0]); //red// 给索引小于数组长度的位置上设置值,即修改该索引位置上的值colors[1] = "black";console.log(colors); // [ 'red', 'black', 'green' ]
    
  2. 通过length属性添加或删除元素

    // 给索引大于数组长度的位置上设置值,即给该数组添加元素,并修改length长度colors[5] = "yellow";console.log(colors); // [ 'red', 'black', 'green', <2 empty items>, 'yellow' ]console.log(colors.length); // 6// 直接修改length属性的值小于原length的值,则删除元素colors.length = 5;console.log(colors[5]); // undefinedconsole.log(colors); // [ 'red', 'black', 'green', <2 empty items> ]
    

6.2.4检测数组

Array.isArray()方法用于确定一个值是否为数组,而不用管它是在哪个全局执行上下文中创建的

let colors = ["red", "blue", "green"];let myColor = "blue";console.log(Array.isArray(colors)); // trueconsole.log(Array.isArray(myColor)); // false

6.2.5迭代器方法(检索数组内容,ES6新增)

  1. keys() 返回数组索引的迭代器

  2. values() 返回数组元素的迭代器

  3. entries() 返回索引/值对的迭代器

    const a = ["foo", "bar", "baz", "qux"];// 因为这引起方法都返回迭代器,所以可以将它们的内容通过Array.from()直接转换为数组实例const aKeys = Array.from(a.keys());console.log(a.keys()); // Object [Array Iterator] {}console.log(aKeys); // [ 0, 1, 2, 3 ]const aValues = Array.from(a.values());console.log(a.values()); // Object [Array Iterator] {}console.log(aValues); // [ 'foo', 'bar', 'baz', 'qux' ]const aEntries = Array.from(a.entries());console.log(a.entries()); // Object [Array Iterator] {}console.log(aEntries); // [ [ 0, 'foo' ], [ 1, 'bar' ], [ 2, 'baz' ], [ 3, 'qux' ] ]
    
  4. 使用解构拆分键值对

    const a = ["foo", "bar", "baz", "qux"];for (const [index, value] of a.entries()) {  console.log(index);  console.log(value);}// 0// foo// 1// bar// 2// baz// 3// qux
    

6.2.6复制和填充方法(ES6新增)

这两个方法都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引,使用这个方法不会改变数组的大小。

  1. 批量复制copyWithin(插入位置,复制索引开始位置,复制索引结束位置):会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置。开始索引与结束索引与fill()使用同样的计算方法。

    let ints,  reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8,9];reset()  // 从ints中复制索引0开始的内容,插入到索引5开始的位置// 在源索引或目标索引到达数组边界时停止 ints.copyWithin(5);console.log(ints); // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]reset();// 从ints中复制索引5开始的内容,插入到索引0开始的位置 ints.copyWithin(0, 5);console.log(ints); // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9]reset();// 从ints中复制索引0开始到索引3结束的内容,插入到索引4开始的位置ints.copyWithin(4, 0, 3);console.log(ints); // [0, 1, 2, 3, 0,1, 2, 7, 8, 9]
    
  2. 填充数组fill(填充元素,填充开始位置,填充结束位置):可以向一个已有的数组中插入全部或部分相同的值,开始索引用于指定开始填充的位置,它是可选的,如果不提供结束索引,则一直填充到数组末尾。负值索引从数组末尾开始计算,也可以将负索引想象成数组长度加上它得到的一个正索引。

    const zeros = [0, 0, 0, 0, 0];// 用5填充整个数组zeros.fill(5); //[ 5, 5, 5, 5, 5 ]console.log(zeros);const zeros1 = [0, 0, 0, 0, 0];// 用6填充大于等于索引3的元素zeros1.fill(6, 3);console.log(zeros1); //[ 0, 0, 0, 6, 6 ]const zeros2 = [0, 0, 0, 0, 0];// 用7填充索引大于等于1且小于等于3的元素zeros2.fill(7, 1, 3);console.log(zeros2); // [ 0, 7, 7, 0, 0 ]const zeros3 = [0, 0, 0, 0, 0];// fill()静默忽略超出数组边界、零长度及方向相反的索引范围zeros3.fill(2, 4, 2);console.log(zeros3); // [ 0, 0, 0, 0, 0 ]
    

6.2.7转换方法

所有对象都有toLocaleString()、toString()、valueOf()方法。

valueOf()方法返回的还是数组本身。

toString()方法返回由数组中每个值的等效字符串拼接而成的一个逗号分隔的字符串,也就是对数组中的每个值都会调用其toString()方法,以得到其最终的字符串。

let colors = ["red", "blue", "green"];console.log(colors.toString()); // red,blue,greenconsole.log(colors.valueOf()); // [ 'red', 'blue', 'green' ]console.log(colors); // [ 'red', 'blue', 'green' ]console.log(colors.toLocaleString()); // red,blue,green

继承的方法toLocaleString()、toString()、都返回数组值的逗号分隔的字符串,如果想使用不同的分隔符,可以使用join()方法,接收一个参数,即字符串分隔符,返回包含所有项的字符串。如果不传入任何参数,或者传入undefined,则仍以逗号作分隔符。

let colors = ["red", "blue", "green"];console.log(colors.join("||")); // red||blue||green

6.2.8栈方法

限制插入和删除项的数据结构。栈是一种后进先出LIFO的结构,也就是最近添加的项先被删除,数据项的插入(推入push)和删除(弹出pop)只在栈的一个地方发生,即栈顶。ECMAScript数组提供了push()和pop()方法,以实现类似栈的行为。

push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的长度。

pop()方法用于删除数组的最后一项,同时减少数组的Length值,返回被删除的项。

let colors = new Array();let count = colors.push("red", "green");console.log(count); // 2count = colors.push("black");console.log(count); // 3// 删除最后一项let item = colors.pop();console.log(item); // blackconsole.log(colors); // [ 'red', 'green' ]

6.2.9队列方法

unshift()方法在数组开头添加任意多个值,然后返回新数组的长度。

shift()(shift单词是去除的意思)方法删除数组的第一项,并返回被删除的元素,然后,数组长度减1。

let colors = new Array();let count = colors.unshift("red", "green");console.log(count); // 2count = colors.unshift("black");console.log(count); // 3console.log(colors); // [ 'black', 'red', 'green' ]let item = colors.shift();console.log(item); // black

6.2.10排序方法

  1. reverse()方法将数组元素反向排列。

    let values = [1, 2, 3, 4, 5];values.reverse();console.log(values); // [ 5, 4, 3, 2, 1 ]
    
  2. sort()方法将数组元素进行排序,默认按升序进行排列。可接收一个比较函数,比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值;如果两个参数相等,就返回0;如果第一个参数应该排在第二个参数后面,就返回正值。

    let values = [0, 1, 5, 10, 15];// sort()会在每项上调用String()转型函数,然后比较字符串来决定顺序,即使数组的元素都是数值,也会先把数组转换为字符串再比较,排序。values.sort();console.log(values); // [ 0, 1, 10, 15, 5 ]// 给sort()传递一个比较函数作为参数function compare(value1,value2) {  if (value1 < value2) {    return -1;  } else if (value1 > value2) {    return 1;  } else {    return 0;   }}let numbers = [0, 1, 5, 10, 15];numbers.sort(compare);console.log(numbers); // [ 0, 1, 5, 10, 15 ]// 如果需要产生降序效果,则交换比较函数中的返回值即可。// 比较函数简写为箭头函数numbers.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);console.log(numbers); // [ 15, 10, 5, 1, 0 ]// 当数组的元素是数值,或者其valueOf()方法返回数值对象(如Date对象),这个比较函数可进一步简化function compare2(a, b) {  return b - a;}// 即最简化版numbers.sort((a, b) => a - b); console.log(numbers); // [ 0, 1, 5, 10, 15 ]
    

6.2.11操作方法

  1. concat()方法:在现有数组全部元素基础上创建一个新数组,它首先会创建一个当前数组的副本,然后再把它的参数添加到副本末尾,最后返回这个新构建的数组。如果传入一个或多个数组,则会把这些数组的每一项都添加到结果数组,如果参数不是数组,则直接把它们添加到结果数组末尾。

    let colors = ["red", "green", "yellow"];let colors2 = colors.concat("yellow", ["black", "brown"]);console.log(colors); // [ 'red', 'green', 'yellow' ]console.log(colors2); // [ 'red', 'green', 'yellow', 'yellow', 'black', 'brown' ]
    
  2. slice()方法:用于创建一个包含原有数组中一个或多个元素的新数组,slice()方法可以接收一个或两个参数:元素的开始索引和结束索引。如果只有一个参数,则返回该索引到数组末尾的所有元素。如果有两个参数,返回开始索引到结束索引对应的元素,不包含结束索引对应的元素,不影响原数组。

    let colors = ['red', 'green', 'blue', 'yellow', 'purple'];let colors1 = colors.slice(1);console.log(colors1); // [ 'green', 'blue', 'yellow', 'purple' ]let colors2 = colors.slice(1, 4);console.log(colors2); // [ 'green', 'blue', 'yellow' ]
    
  3. splice()方法:在数组中间插入元素。

    • 删除:传入两个参数,要删除的第一个元素的位置和要删除元素的数量。可以从数组中删除任意个元素。
    • 插入:传入三个参数,开始位置,0(要删除的元素数量),要插入的元素,可以在数组中指定位置插入元素,第三个参数后可以有任意多个插入的元素。
    • 替换:在删除元素的同时在指定位置插入新元素,传入三个参数,开始位置,要删除元素的数量,要插入的任意多个元素。要插入元素的数量不一定跟要删除的元素数量一致。
    let colors = ['red', 'green', 'blue'];let removed = colors.splice(0, 1);console.log(removed); // [ 'red' ]console.log(colors); // [ 'green', 'blue' ]removed = colors.splice(1, 0, "yellow", "orange");console.log(removed); // []removed = colors.splice(1, 1, "red", "purple");console.log(removed); // [ 'yellow' ]
    

6.2.12搜索和位置方法

  1. 严格相等

    • indexOf()、lastIndexOf()、includes(),第三个方法是ES7新增的。
    • 这些方法都接收两个参数:要查找的元素和一个可选的起始搜索位置。
    • indexOf() 和 includes()方法从数组前头(第一项)开始向后搜索,而lastIndexOf()从数组末尾(最后一项)开始向前搜索。
    • indexOf() 和 lastIndexOf()都返回要查找的元素在数组中的位置,如果没找到返回-1.
    • includes()返回布尔值,表示是否至少找到一个与指定元素匹配的项,在比较第一个参数跟数组中每一项时,会使用全等(===)比较,也就是严格相等。
    let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];console.log(numbers.indexOf(4)); // 3console.log(numbers.lastIndexOf(4)); // 5console.log(numbers.includes(4)); // trueconsole.log(numbers.indexOf(4,4)); //5console.log(numbers.lastIndexOf(4,4)); // 3console.log(numbers.includes(4, 7)); // falselet person = { name: "Nick" };let people = [{ name: "Nick" }];let morePeople = [person];// 在people这个数组里,查找person这个人console.log(people.indexOf(person)); // -1console.log(people.includes(person)); // falseconsole.log(morePeople.indexOf(person)); // 0console.log(morePeople.includes(person)); //true
    
  2. 断言函数

    • 每个索引都会调用这个函数,断言函数的返回值决定了相应索引的元素是否被认为匹配。
    • 接收三个参数:元素,索引和数组本身。元素是数组中当前搜索的元素,索引是当前元素的索引,面数组就是正在搜索的数组,断言函数返回真值,表示是否匹配。
    • find()、findIndex()这两个方法都从数组的最小索引开始,find()返回第一个匹配的元素,findIndex()返回第一个匹配元素的索引。这两个方法也都接收第二个可选的参数,用于指定断言函数内部this的值。找到匹配项后,这两个方法都不再继续搜索。
    const people = [  { name: "Matt", age: 27 },  { name: "Nich", age: 29 }];console.log(people.find((element, index, array) => element.age < 28)); //{ name: 'Matt', age: 27 }console.log(people.findIndex((element, index, array) => element.age < 28)); // 0const evens = [2, 4, 6];evens.find((element, index, array) => {  console.log(element);  console.log(index);  console.log(array);})// 2// 0// [2, 4, 6]// 4// 1// [2, 4, 6]// 6// 2// [2, 4, 6]
    

6.2.13迭代方法

ECMAScript为数组定义了5个迭代方法,每个方法接收两个参数:以每一项为参数运行的函数,以及可选的作为函数运行上下文的作用域对象(影响函数中this的值),传给每个方法的函数接收3个参数:数组元素,元素索引和数组本身。

  1. every():对数组每一项都运行传入的函数,如果对每一项函数都返回true,则这个方法返回true;
  2. filter():对数组每一项都运行传入的函数,函数返回true的项会组成数组之后返回;
  3. forEach():对数组每一项都运行传入的函数,没有返回值;
  4. map():对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组;
  5. some():对数组每一项都运行的函数,如果有一项函数返回true,则这个方法返回true;

这些方法都不改变调用它们的原数组。

let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let everyResult = numbers.every(item => item > 2);
console.log(everyResult); // false

let someResult = numbers.some(item => item > 2);
console.log(someResult); // true

let filterResult = numbers.filter(item => item > 2);
console.log(filterResult); // [ 3, 4, 5, 4, 3 ]

let mapResult = numbers.map(item => item * 2);
console.log(mapResult); // [2, 4, 6, 8, 10,8, 6, 4, 2]

numbers.forEach((item, index, array) => {
  // 执行某些操作
})

6.2.14归并方法

  1. ECMAScript提供了两个归并方法reduce()reduceRight()。这两个方法都会迭代数组的所有项,并在此基础上构建一个最终返回值。
  2. reduce()方法从数组第一项遍历到最后一项,而reduceRight()从最后一项开始遍历到第一项。
  3. 这两个方法都接收两个参数:对每一项都会运行的归并函数,以及可选的以之为归并起点的初始值。
  4. 传给reduce()reduceRight()的函数接收4个参数:上一个归并值,当前项,当前项的索引,数组本身。这个函数返回的任何值都会作为下一次调用同一个函数的第一个参数。
  5. 如果没有给这两个方法传入可选的第二个参数(作为归并起点),则第一次迭代将从数组的第二项开始,因此传给归并函数的第一个参数是数组的第一项,第二个参数是数组的第二项。
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
console.log(sum); // 15

let sum1 = values.reduceRight((prev, cur, index, array) => prev + cur);
console.log(sum1); // 15
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值