《jacascript高级程序设计》笔记:数组方法高级

这一章节主要记录的是ES5的方法,在低版本浏览器上存在一定的兼容,但是主流手机上使用大可放心。

位置方法

ECMAScript 5 为数组实例添加了两个位置方法:indexOf()和 lastIndexOf()。

1.参数: 要查找的项和(可选的)表示查找起点位置的索引。
2.indexOf()方法从数组的开头(位置0)开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找
3.两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1
4.在比较第一个参数与数组中的每一项时,会使用全等操作符

var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4));        //3

alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4));     //5
alert(numbers.lastIndexOf(4, 4)); //3

var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person));     //-1
alert(morePeople.indexOf(person)); //0

迭代方法

声明:以下方法参数都是function类型,默认有传参,方法中的function回调支持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本身

1.forEach()方法
【遍历】遍历数组,没有返回值!没有返回值!没有返回值!重要的事情说三遍
forEach()方法几乎可以代替for的用法,如果对数组的返回或跳出没有要求

用法:

[1, 2 ,3, 4].forEach(function(value, index, arr){
    console.log(value); // 当前值
    console.log(index); // 当前索引
    console.log(arr); // 指向当前数组
});

// 等同于
var array = [1, 2, 3, 4];
for (var k = 0, length = array.length; k < length; k++) {
    //...
}

用法虽然简单,但在低版本的浏览器上存在兼容,下面提供一个兼容性的写法:

// 对于古董浏览器,如IE6-IE8

if (typeof Array.prototype.forEach != "function") {
  Array.prototype.forEach = function (fn, context) {
    for (var k = 0, length = this.length; k < length; k++) {
      if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, k)) {
        fn.call(context, this[k], k, this);
      }
    }
  };
}

2.map()方法

【映射】对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组,返回的数组长度一定与原数组长度相同,常用来改造某一数组,例如对某段数组进行筛选或插入新的元素

基本用法:

// 含有return
[1, 2, 3, 4].map(function (item) {
  return item * item; // [1, 4, 9, 16]
});

// 不含return
[1, 2, 3, 4].map(function (item) {
  item * item; // [undefined, undefined, undefined, undefined]
});

用于筛选某一段数组,返回符合要求对元素组成的新数组:

var users = [
  {name: "佟丽娅", "email": "zhang@email.com"},
  {name: "赵丽颖",   "email": "jiang@email.com"},
  {name: "肉巴",  "email": "li@email.com"}
];

var emails = users.map(function (user) { return user.email; });
// ["zhang@email.com", "jiang@email.com", "li@email.com"]

用于插入新的元素:

var users = [
  {name: "佟丽娅", "email": "tongliya@email.com"},
  {name: "赵丽颖",   "email": "zhaoliying@email.com"},
  {name: "肉巴",  "email": "dilireba@email.com"}
];
users.map(function(v){
    v.enName = v.email.slice(0, v.email.indexOf('@'));
    return v
})

兼容性写法:

if (typeof Array.prototype.map != "function") {
  Array.prototype.map = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
      for (var k = 0, length = this.length; k < length; k++) {      
         arr.push(fn.call(context, this[k], k, this));
      }
    }
    return arr;
  };
}

3.filter()方法

【筛选】对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组
与map()方法的用法较为相似,但是仅返回满足要求的项,返回的新的数组一定是原数组中的元素,且数组长度小于等于原数组长度

基本用法

[0, 1, 2, 3].filter(function(item) {
    return item; // [1, 2, 3]
});

var users = [
  {name: "佟丽娅", "email": "tongliya@email.com", age: 24},
  {name: "赵丽颖",   "email": "zhaoliying@email.com", age: 18},
  {name: "肉巴",  "email": "dilireba@email.com", age: 17}
];
users.map(function(v){
    return v.age > 18// {name: "佟丽娅", email: "tongliya@email.com", age: 24}
})

兼容性写法:

if (typeof Array.prototype.filter != "function") {
  Array.prototype.filter = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
       for (var k = 0, length = this.length; k < length; k++) {
          fn.call(context, this[k], k, this) && arr.push(this[k]);
       }
    }
    return arr;
  };
}

every()方法

【全满足返回true】对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true

基本用法:

// 数组中所有项满足要求时返回true,否则为false
[1,2,3,4,5,6,7].every(function(v){
    return v > 2; // false
})

兼容性写法:

if (typeof Array.prototype.every != "function") {
  Array.prototype.every = function (fn, context) {
    var passed = true;
    if (typeof fn === "function") {
       for (var k = 0, length = this.length; k < length; k++) {
          if (passed === false) break;
          passed = !!fn.call(context, this[k], k, this);
      }
    }
    return passed;
  };
}

some()方法

【某项满足返回true】对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true

基本写法

// 数组中某一项满足要求时返回true,否则为false
[1,2,3,4,5,6,7].some(function(v){
    return v > 2; // true
})

兼容性写法:

if (typeof Array.prototype.some != "function") {
  Array.prototype.some = function (fn, context) {
    var passed = false;
    if (typeof fn === "function") {
         for (var k = 0, length = this.length; k < length; k++) {
          if (passed === true) break;
          passed = !!fn.call(context, this[k], k, this);
      }
    }
    return passed;
  };
}

归并方法

归并方法包括reduce()和reduceRight()两种,写法同上面的方式相似。函数接受4个参数:之前值、当前值、索引值以及数组本身。initialValue参数可选,表示初始值。若指定,则当作最初使用的previous值;如果缺省,则使用数组的第一个元素作为previous初始值,同时current往后排一位,相比有initialValue值少一次迭代

1.reduce()方法

基本用法:

var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {
  return previous + current;
});

console.log(sum); // 10

// 执行过程
// 初始设置
previous = initialValue = 1, current = 2
// 第一次迭代
previous = (1 + 2) =  3, current = 3
// 第二次迭代
previous = (3 + 3) =  6, current = 4
// 第三次迭代
previous = (6 + 4) =  10, current = undefined (退出)
var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {
  return previous + current;
}, 10);

console.log(sum); // 20
// 执行过程
// 初始设置
initialValue = 10, previous = 1, current = 2
// 第一次迭代
previous = (10 + 1) =  11, current = 2
// 第二次迭代
previous = (11 + 2) =  13, current = 3
// 第三次迭代
previous = (13 + 3) =  16, current = 4
// 第四次迭代
previous = (16 + 4) =  20, current = undefined

数组扁平化

var matrix = [
  [1, 2],
  [3, 4],
  [5, 6]
];

// 二维数组扁平化
var flatten = matrix.reduce(function (previous, current) {
  return previous.concat(current);
});

console.log(flatten); // [1, 2, 3, 4, 5, 6]

兼容写法:

if (typeof Array.prototype.reduce != "function") {
  Array.prototype.reduce = function (callback, initialValue ) {
     var previous = initialValue, k = 0, length = this.length;
     if (typeof initialValue === "undefined") {
        previous = this[0];
        k = 1;
     }
     
    if (typeof callback === "function") {
      for (k; k < length; k++) {
         this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
      }
    }
    return previous;
  };
}

2.reduceRight()方法

与reduce()方法相同,只是执行顺序是从右往左

兼容性写法:

if (typeof Array.prototype.reduceRight != "function") {
  Array.prototype.reduceRight = function (callback, initialValue ) {
    var length = this.length, k = length - 1, previous = initialValue;
    if (typeof initialValue === "undefined") {
        previous = this[length - 1];
        k--;
    }
    if (typeof callback === "function") {
       for (k; k > -1; k-=1) {          
          this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
       }
    }
    return previous;
  };
}

参考:ES5中新增的Array方法详细说明

    原文作者:同梦奇缘
    原文地址: https://segmentfault.com/a/1190000010779315
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞