call,apply,bind函数对比及实现

文章详细对比了JavaScript中的call、apply和bind方法,它们都能改变函数中this的指向,同时也提供了这三种方法的简单实现。call和apply主要区别在于参数传递方式,call接受多个参数,apply接受一个数组或类数组。bind则不会立即执行函数,而是返回一个新的绑定上下文的函数。

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

目录

对比

相同

不同

简单实现

call

分析

整体代码

apply

分析

整体代码

bind


对比

相同

  1. 均能改变this的指向
  2. 接收的第一个参数均为this指向的对象
  3. 后面的参数都可以进行传参

不同

  1. 参数:call和bind相同,均支持多个参数依次传入;apply仅支持数组或类数组
  2. 调用:call和apply在运行时都调用了函数,而bind不调用

简单实现

call

分析

function.call(thisArg, arg1, arg2, ...)

1.调用function:function必须存在且是一个函数,之后调用并返回

if (typeOf this !== "function") {
      throw new TypeError("error")
  }
result = this() //当前为function
return result

2.传入参数thisArg,如果没有传入参数,则默认为window

context = context || window

3.指针从function变化为thisArg(这里相当于给thisArg添加一个fn属性,值为function)

 context.fn = this
  • 最后需要删除
delete context.fn

4.取参数call传的参数(从第二个开始截取)

let args = [...arguments].slice(1)

5.调用函数并传参

result = context.fn(...args)

6.返回值

整体代码

Function.prototype.myCall = function (context) {
    if (typeOf this !== "function") {
        throw new TypeError("error")
    }
    context = context || window
    context.fn = this
    let args = [...arguments].slice(1)
    let result = null
    result = context.fn(...args)
    delete context.fn
    return result
}

apply

分析

apply(thisArg)
apply(thisArg, argsArray)

整体上和call一样,只有参数不同,apply第二个参数为数组

  • 获取数组以及调用
  • 传参:如果传入了数组,则使用展开运算符
 if (arguments[1]) {
        result = context.fn(...arguments[1])
    } else {
        result = context.fn()
    }

整体代码

Function.prototype.myApply = function (context) {
    if (typeOf this !== "function") {
        throw new TypeError("error")
    }
    context = context || window
    context.fn = this
    let result = null

    if (arguments[1]) {
        result = context.fn(...arguments[1])
    } else {
        result = context.fn()
    }

    delete context.fn
    return result
}

bind

Function.prototype.myBind = function (context) {
    //1.判断调用对象是否为函数
    if (typeOf this !== "function") {
        throw new TypeError("error")
    }
    //2.保留当前函数的引用,获取其余值传入参数
    var fn = this
    var args = [...arguments].slice(1)
    //3.创建函数返回
    return function Fn() {
        //4.调用apply 
        return fn.apply(
            //判断函数作为构造函数的情况
            this instanceof Fn ? this : context,
            args.concat(...arguments)
        )
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值