手写代码篇

169 阅读2分钟

初学者的手写代码学习😄😄😄

Call的实现

  • call()  方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
  • 第一个参数为null或者undefined时,this指向全局对象window,值为原始值时指向该原始值的自动包装对象,如String、Number、Boolean等
  • 为了避免函数名与上下文context中的属性发生冲突,使用Symbol类型作为唯一值
  • 将函数作为传入的上下文context属性执行
  • 函数执行完后删除该属性
  • 返回执行结果
 Function.prototype.myCall = function(context,...args){
     // context 为null 或者 undefined时为window
     let cxt = context || window
     //新建一个唯一的symbol变量避免重复
     let func = new Symbol()
     //将当前被调用的方法定义在cxt[func]上(为了能以对象调用形式绑定this)
     ctx[func] = this
     
     args = args? args:[]
     //调用函数
     const res = args.length >0 ? cxt[func](...args) : cxt[func]()
     //删除该方法,不然传入对象造成污染
     delete cxt[func]
     
     return res
  }

apply的实现

  • apply()  方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
  • apply方法与call方法一样,唯一不同的传入第二个参数为数组类型
  • 第一个参数为null或者undefined时,this指向全局对象window,值为原始值时指向该原始值的自动包装对象,如String、Number、Boolean等
  • 为了避免函数名与上下文context中的属性发生冲突,使用Symbol类型作为唯一值
  • 将函数作为传入的上下文context属性执行
  • 函数执行完后删除该属性
  • 返回只想结果
Function.prototype.myApply = function(context,args = []){
    let cxt = context || window
    
    let func = new Symbol()
    
    cxt[func] = this
     args = args? args:[]
     //调用函数
     const res = args.length >0 ? cxt[func](...args) : cxt[func]()
     //删除该方法,不然传入对象造成污染
     delete cxt[func]
     
     return res
  }
    

bind的实现

  • bind()  方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
  • 需要考虑:
    • bind()除了this外,还可以传入多个参数
    • bind创建的新韩淑可能传入多个参数
    • 函数可能有返回值
 Function.protptype.myBind = function(context,...args){
     
     let cxt = context || window
     //获取到真实需要调用的函数
     var fn = this
     args = args ? args:[]
     return newFunction(...newArgs){
         let func = new Symbol() 
         cxt[func] = fn
         
         let res = cxt[func](...args,...newArgs)
         
         delete cxt[func]
         
         return res
     }
 }