map取第一个元素_手写map() reduce() call() apply() bind()

1.实现bind()

ECMAScript3版本的Function.bind()方法。——来自《JavaScript权威指南》 P191

if(!Function.prototype.bind) {
  Function.prototype.bind = function(o /* , args */) {
    // 将this和arguments的值保存至变量中以便在后面嵌套的函数中可以使用它们
    var self = this, boundArgs = arguments;

    // bind()方法的返回值是一个函数
    return function() {
      // 创建一个实参列表,将传入bind()的第二个及后续的实参都传入这个函数
      var i, args = [];
      for(i = 1; i < boundArgs.length; i++){ args.push(boundArgs[i]) }
      for(i = 0; i < arguments.length; i++){ args.push(arguments[i]) }
      // 现在将self作为o的方法来调用,传入这些实参
      return self.apply(o, args)
    }
  }
}

4fc6e918bcd0c373e3045e0b4cc96143.png

2.实现map()

*Array.prototype.map()*返回一个由回调函数的返回值组成的新数组

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
// 参数callback:生成新数组元素的函数,
// 使用三个参数-
// currentValue:callback数组中正在处理的当前元素;
// index: 可选。callback数组中正在处理的当前元素的索引;
// array:可选。callbackmap 方法被调用的数组。
// 参数thisArg:可选。执行 callback 函数时使用的this值。如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this都会指向 thisArg参数上的这个对象。如果省略了 thisArg 参数,或者赋值为 null或undefined,则 this 指向全局对象 。

ECMAScript3自定义map()——来自来自《JavaScript权威指南》 P195

// 对于每个数组元素调用函数f(),并返回一个结果数组
var map = Array.prototype.map               // 如果Array.prototype.map定义了的话就使用这个方法
    ? function(a,f) {return a.map(f)}       // 如果已经存在map方法,就直接使用它
    : function(a,f) {                       // 否则自己实现一个
        var results = [];
        for (var i = 0, len = a.length; i < len; i++) {
            if (i in a) results[i] = f.call(null, a[i], i, a)
        }
        return results;
    };

3ebe6ede2f500fc40a82d4d672c2ba73.png

3.实现reduce()

Array.prototype.reduce()*从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
// 参数callback:执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数-
// accumulator:累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue;
// currentValue:数组中正在处理的元素;
// index:可选。数组中正在处理的当前元素的索引。如果提供了initialValue,则起始索引号为0,否则从索引1起始;
// array:可选。调用reduce()的数组。
// 参数initialValue:可选。
// 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 
// 在没有初始值的空数组上调用 reduce 将报错。
// 返回值:函数累计处理的结果。

ECMAScript3自定义reduce()——来自来自《JavaScript权威指南》 P195

// 使用函数f()和可选的初始值将数组a减至一个值
var reduce = Array.prototype.reduce          // 如果Array.prototype.reduce存在的话,就使用这个方法
    ? function(a, f, initial) {              // 如果reduce()方法存在的话
        if (arguments.length > 2) {
            return a.reduce(f, initial);     // 如果传入了一个初始值
        } else {
            return a.reduce(f)               // 否则没有初始值
        }
    }
    : function(a, f, initial) {              // 这个算法来自ES5规范
        var i = 0, len = a.length, accumulator;
        if (arguments.length > 2) accumulator = initial; // 以特定的初始值开始,否则第一个值取自a
        else {                                          // 找到数组中第一个已定义的索引
            if (len == 0) throw TypeError();
            while (i < len) {
                if (i in a) {
                    accumulator = a[i++];
                    break;
                }
                else i++;
            }
            if (i == len) throw TypeError();
        }
        // 对于数组中剩下的元素依次调用f()
        while (i < len) {
            if (i in a) { accumulator = f.call(undefined, accumulator, a[i], i, a)};
            i++;
        }
        return accumulator;
    }

264ddef3636b0aaf8d4cf5a2d0dd64f3.png

4.实现call()

Function.prototype.call()在一个对象的上下文中应用另一个对象的方法;参数能够以列表形式传入。

Function.prototype.myCall = function() {
  if (typeof this !== 'function') throw new Error('Must call with a function')
  var realThis = arguments[0] || window;
  var realArgs = [...arguments].slice(1);
  realThis.func1 = this; // 此this是原方法,保存到传入的第一个参数上
  // 用传入的参数来调方法,方法里的this就是传入的参数了
  var result = realThis.func1(...realArgs)
  delete realThis.func1     // 最后删掉临时存储的原方法
  return result             // 将执行的返回值返回
}

63a713097e9665c75494e461682d3059.png

5.实现apply()

Function.prototype.apply()在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。

Function.prototype.myApply = function() {
  if (typeof this !== 'function') throw new Error('Must call with a function')
  var realThis = arguments[0] || window;
  var realArgs = arguments[1];  // 直接取第二个参数,是一个数组
  realThis.func1 = this; // 此this是原方法,保存到传入的第一个参数上
  // 用传入的参数来调方法,方法里的this就是传入的参数了
  var result = realThis.func1(...realArgs)
  delete realThis.func1
  return result
}

e1ce94d2375ad513db3af77da21e6e7a.png

本文引用:

JavaScript权威指南(第6版) (豆瓣)​book.douban.com
729af9aa2ca834f67770281846130cf7.png
this到底指向啥?看完这篇就知道了! - 掘金​juejin.im
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值