call-apply-bind.md

call

先看call做了什么?

  1. call的第一个参数为函数体内部的this指向
  2. 其余作为参数单个传入(非数组)函数体
  3. 立即执行函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Function.prototype.myCall = (context) => {
    if(typeof this !== 'function') {
    throw new TypeError('Error')
    }

    context = context || window
    context.fn = this
    const args = [...arguments].slice(1)
    const result = context.fn(...args)
    delete context.fn
    return result
    }

    apply

    与call的区别在于第一个参数后的传参方式, 是以数组的方式传入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Function.prototype.myApply = (context) => {
    if(typeof this !== 'function') {
    throw new TypeError('Error')
    }

    context = context || window
    context.fn = this
    const args = [...arguments].slice(1)
    const result = context.fn(args)
    delete context.fn
    return result
    }

bind 主要注意一点是, 记得区分出new和普通调用的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Function.prototype.myBind = (context) => {
if(typeof this !== 'function') {
throw new TypeError('Error')
}

// 获取到函数体
const fnBody = this
const args = [...arguments].slice(1)
return function F() {
// 当使用new 方法调用该函数时
if(this instanceof F) {
return new fnBody(...args, ...arguments)
}
// 正常调用
return fnBody.apply(context, args.concat(...arguments))
}
}