手写call,apply和bind函数

手写call的实现

思路
let person = {
    name: 'tom1',
    say(){
        console.log(this)
        console.log(`my name is ${this.name}`)
    }
}
let person2 = {
    name: 'tom2'
}
Function.prototype.myCall = function (context) {
    console.log(this)    // 调用myCall的环境即为 person.say 函数
    console.log(context) // person2
    context.fn = this    // 在person2 环境中加入一个新的函数fn,指向say
    context.fn() // 在person环境中运行 fn函数(say函数)
}
person.say.myCall(person2)
具体实现
Function.prototype.myCall = function(context) {
     if(typeof this !== 'function'){
         throw new TypeError('Error')
     }
}
// 如果没有传或传的值为空对象,context指向window
context = context || windows
context.fn = this
let arg = [...arguments].slice(1)
context.fn(...arg)
delete context.fn

手写apply的实现

Function.prototype.myApply = function(context) {
    if(typeof this!== 'function') {
        throw new TypeError('Error')
    }
    context = context || window
    context.fn = this
    if(arguments[1]){
        context.fn(...arguments[1])
    }else{
        context.fn()
    }
}
person.say.myApply(person2)

手写bind的实现

Function.prototype.myBind = function(context){
   if(typeof this !== 'function') {
       throw new TypeError('Error')
   }
   let self =this
   let arg = [...arguments].slice(1)
   return function Newfn(){
   // 因为柯里化形式传参,可实现f.bind(obj, 1)(2)
       let newArg = [...arguments]
       return sef.apply(context,arg.concat(newArg))
   }
}