javascript 模拟实现call apply 和bind

源码

  还没找到

比较

  1.   js中的call apply bind  都改变了this指向(函数运行时的上下文)____ 【关于上下文等一段时间再分析
  2.   call 和apply 功能是类似的,只是传参方式不同:
    •   call(上下文,参数1,参数2,.....)
    •        apply(上下文,[参数1,参数2,.....]) 
  3.   bind 返回一个函数

用法

  1. 改变this指向     
  2. 借用自身没有的方法

实质

var lucky ={
    name:'lucky',
    age:18,
}
function selfIntroduction(){
    console.log('我的名字是'+this.name , '今年'+this.age)}

selfIntroduction.call(lucky)

我的名字是lucky 今年18

表面上看 call 改变了 selfIntroduction 函数的 this 指向,使 this 指向了 lucky

其实改变 this 指向的方法是 将 selfIntroduction 函数赋值给 lucky 对象(用完再删除) :

Function.prototype.callCall = function(context){ 
var context= context || window

context.fn = this  //将调用的函数放进context中

  context.fn()       //调用函数

  delete context.fn  //删除添加到context中的函数 

}

对于 call 函数 中的参数可以用arguments 获取

Function.prototype.callCall = function(context){
  var context = context || window   context.fn
= this //将调用的函数放进context中 var arg = [] for(var i = 1 ,lenth=arguments.length; i<length ;i++){ arg.push('arguments[' + i + ']') }   eval('context.fn(' + arg + ')')//调用 eval 函数传arg参数  

  delete context.fn //删除添加到context中的函数 }

还需注意的地方:

  1.   call的第一个参数可能是 null
Function.prototype.callCall = function(context){ 
  var context = context || window   context.fn
= this //将调用的函数放进context中 var arg = [] for(var i = 1 ,lenth=arguments.length; i<length ;i++){ arg.push('arguments[' + i + ']') }   eval('context.fn(' + arg + ')')//调用 eval 函数传arg参数     delete context.fn //删除添加到context中的函数 }

          2.  函数有返回值

Function.prototype.callCall = function(context){ 
  var context = context || window
  context.fn = this  //将调用的函数放进context中
    var arg = []
    for(var i = 1 ,lenth=arguments.length; i<length ;i++){
         arg.push('arguments[' + i + ']') 
}
  var result = eval('context.fn(' + arg + ')')//调用 eval 函数传arg参数  

  delete context.fn //删除添加到context中的函数   } 
   return result

至此 call 的模拟已经完成(等下次遇到call ,apply,bind 不理解了再后续更新)

 

学习于 冴羽 及网上能查到的各种资料 博客

有理解不对的地方评论或者私信可以讨论💯

 

    

posted @ 2020-01-08 16:16  崔嵬  阅读(105)  评论(0编辑  收藏  举报