Karam
Articles71
Tags52
Categories15
call和apply函数区别

call和apply函数区别

call和apply的作用及区别

call和apply通常用来修改this的指向
call和apply的区别仅是传递的参数的个数不一样,apply函数仅有两个参数,第一个参数是需要修改的上下文环境的对象,第二个参数是数组或者类数组,为传递的参数的列表。
call的参数个数没有限制,最少有一个,第一个为需要修改的上下文环境对象,其余都为参数

手写call和apply函数

apply的执行逻辑是:

  1. 先判断调用对象的类型是否为Function
  2. 修改this的指向
  3. 执行函数
  4. 删除保存的this指向
  5. 返回函数执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Function.prototype.myapply = function (context) {
    //检查类型
    if(typeof this !== 'function') {
    throw new TypeError('not a Function')
    }
    //获取上下文环境
    context = context || window
    //保存this指向
    context.fn = this
    //获取参数列表
    let args = arguments[1]
    //执行函数,保存执行结果
    let result = context.fn(...args)
    //删除this指向
    delete context.fn
    //返回函数执行结果
    return result
    }
    call的执行逻辑和apply差不多,不同的是参数列表的的传递:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Function.prototype.mycall = function (context) {
    //检查类型
    if(typeof this !== 'function') {
    throw new TypeError('not a Function')
    }
    //获取上下文环境
    context = context || window
    //保存this指向
    context.fn = this
    let args = [...arguments].slice(1)
    //执行函数,保存执行结果
    let result = context.fn(...args)
    //删除this指向
    delete context.fn
    //返回函数执行结果
    return result
    }

    bind函数

    bind函数其实是上面apply的语法糖,区别在于,参数列表不同,而且bind不会立即调用函数,而是返回一个函数
    1
    2
    3
    4
    5
    6
    Function.prototype.mybind = function (context, ...args) {
    let _self = this
    return function () {
    return _self.apply(context, args)
    }
    }