ES5 数组方法之-----map

ES5 数组方法map

概述

map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。

语法

array.map(callback[, thisArg])

参数

callback

原数组中的元素经过该方法后返回一个新的元素。

currentValue

callback 的第一个参数,数组中当前被传递的元素。

index

callback 的第二个参数,数组中当前被传递的元素的索引。

array

callback 的第三个参数,调用 map 方法的数组。

thisArg

执行 callback 函数时 this 指向的对象。

例子:将数组中的单词转换成对应的复数形式.

下面的代码将一个数组中的所有单词转换成对应的复数形式.

 

function fuzzyPlural(single) {
  var result = single.replace(/o/g, 'e');  
  if( single === 'kangaroo'){
    result += 'se';
  }
  return result; 
}

var words = ["foot", "goose", "moose", "kangaroo"];
console.log(words.map(fuzzyPlural));

// ["feet", "geese", "meese", "kangareese"]

例子:求数组中每个元素的平方根

下面的代码创建了一个新数组,值为原数组中对应数字的平方根。

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
/* roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9] */

例子:在字符串上使用 map 方法

下面的例子演示如在在一个 String  上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组:

var map = Array.prototype.map
var a = map.call("Hello World", function(x) { return x.charCodeAt(0); })
// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

使用技巧案例

通常情况下,map 方法中的 callback 函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。

 

// 下面的语句返回什么呢:
["1", "2", "3"].map(parseInt);
// 你可能觉的会是[1, 2, 3]
// 但实际的结果是 [1, NaN, NaN]

// 通常使用parseInt时,只需要传递一个参数.但实际上,parseInt可以有两个参数.第二个参数是进制数.可以通过语句"alert(parseInt.length)===2"来验证.
// map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 元素索引, 原数组本身.
// 第三个参数parseInt会忽视, 但第二个参数不会,也就是说,parseInt把传过来的索引值当成进制数来使用.从而返回了NaN.

/*
//应该使用如下的用户函数returnInt

function returnInt(element){
  return parseInt(element,10);
}

["1", "2", "3"].map(returnInt);
// 返回[1,2,3]
*/

兼容旧环境(Polyfill)

map 是在最近的 ECMA-262 标准中新添加的方法;所以一些旧版本的浏览器可能没有实现该方法。在那些没有原生支持 map 方法的浏览器中,你可以使用下面的 Javascript 代码来实现它。所使用的算法正是 ECMA-262,第 5 版规定的。假定ObjectTypeError, 和 Array 有他们的原始值。而且 callback.call 的原始值也是 Function.prototype.call

 

// 实现 ECMA-262, Edition 5, 15.4.4.19
// 参考: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }

    // 1. 将O赋值为调用map方法的数组.
    var O = Object(this);

    // 2.将len赋值为数组O的长度.
    var len = O.length >>> 0;

    // 3.如果callback不是函数,则抛出TypeError异常.
    if (Object.prototype.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }

    // 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 5. 创建新数组A,长度为原数组O长度len
    A = new Array(len);

    // 6. 将k赋值为0
    k = 0;

    // 7. 当 k < len 时,执行循环.
    while(k < len) {

      var kValue, mappedValue;

      //遍历O,k为原数组索引
      if (k in O) {

        //kValue为索引k对应的值.
        kValue = O[ k ];

        // 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
        mappedValue = callback.call(T, kValue, k, O);

        // 返回值添加到新数组A中.
        A[ k ] = mappedValue;
      }
      // k自增1
      k++;
    }

    // 8. 返回新数组A
    return A;
  };      
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我理解您的问题了。其实在ES5中的数组高阶函数本质上也是利用了原型的特性。不过在ES6中引入了箭头函数和更加简洁的语法,使得使用高阶函数更加方便。下面我将通过重构ES5中的数组高阶函数来展示如何利用原型的特性。 首先,我们来看一下ES5中的数组高阶函数的写法: ``` var arr = [1, 2, 3, 4, 5]; // map var newArr = arr.map(function(item) { return item * 2; }); // filter var filteredArr = arr.filter(function(item) { return item > 3; }); // reduce var reducedValue = arr.reduce(function(acc, item) { return acc + item; }, 0); ``` 现在我们来利用原型的特性,将这些高阶函数封装到数组的原型中: ``` Array.prototype.myMap = function(callback) { var newArr = []; for (var i = 0; i < this.length; i++) { newArr.push(callback(this[i], i, this)); } return newArr; }; Array.prototype.myFilter = function(callback) { var filteredArr = []; for (var i = 0; i < this.length; i++) { if (callback(this[i], i, this)) { filteredArr.push(this[i]); } } return filteredArr; }; Array.prototype.myReduce = function(callback, initValue) { var acc = initValue || this[0]; var startIndex = initValue ? 0 : 1; for (var i = startIndex; i < this.length; i++) { acc = callback(acc, this[i], i, this); } return acc; }; ``` 现在我们就可以像使用ES5中的数组方法一样来使用我们的自定义方法了: ``` var arr = [1, 2, 3, 4, 5]; // myMap var newArr = arr.myMap(function(item) { return item * 2; }); // myFilter var filteredArr = arr.myFilter(function(item) { return item > 3; }); // myReduce var reducedValue = arr.myReduce(function(acc, item) { return acc + item; }, 0); ``` 以上就是用原型的特性重构ES5中的数组高阶函数的方法。希望可以帮助到您!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值