Function.apply.bind(foo,null)解析

本文详细解析了JavaScript中Function.apply与bind方法的工作原理,并通过实际代码示例展示了如何使用这些方法来改变函数的调用上下文。文章还提供了一个接近原生实现的bind方法示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

前些天看到遇到Function.apply.bind(foo,null)这么一行代码,冥思苦想而不得,终于今日下了决心把它解决掉。

内容

一、要理解这行代码,当然首先得理解apply和bind的相关特性了。
apply:调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。详情见这里

bind:函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。当新函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。详情见这里

二、模拟原生的bind实现代码如下

//最接近原生的bind实现方法,基于此进行分析
Function.prototype.bind = function(oThis) {
  if (typeof this !== "function") {
    throw new TypeError("Function.prototype.bind");
  }
  //debugger;
  var aArgs = Array.prototype.slice.call(arguments, 1),
    fToBind = this,
    fNOP = function() {},
    fBound = function() {
      //debugger;
      return fToBind.apply(
        this instanceof fNOP ? this : oThis,
        // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
        // 此时aArgs=[null]
        aArgs.concat(Array.prototype.slice.call(arguments))
      );
    };

  // 维护原型关系
  if (this.prototype) {
    // Function.prototype doesn't have a prototype property
    fNOP.prototype = this.prototype;
  }
  fBound.prototype = new fNOP();

  return fBound;
};

三、用例及代码解析

function foo(x, y) {
  console.log(x, y);
}

function spread(fn) {
  return Function.apply.bind(fn, null);
}

spread(foo)([3, 10]);

//代码解析:
/*

spread(foo)([3, 10])  ==> 

Function.apply.bind(foo,null)([3, 10]) ==> 

function() {
    //此时aArgs = [null]
    return apply.apply(foo,aArgs.concat(Array.prototype.slice.call(arguments)));
}([3, 10]) ==> 

//此时第一个apply是作为业务方法,第二作为apply工具方法,因此会把参数解构成列表形式
 return apply.apply(foo,[null,3,10]) ==> 

 //根据apply方法语义(指定为函数指定执行this)得到等价执行代码
 return foo.apply(null,3,10) ==>

 //当apply指定的thisnull时,非严格模式下会自动指向全局对象
 foo(3,10)//3,10

*/

结束语

有不对的地方请诸位同仁指正。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值