js中关于call的源码解析

js中关于call源码的解析

call、apply、bind

三个方法都是改变函数中的 this 指向;只有是Function的实例才可以使用这三个方法。

首先函数中的this 不能放在等号的左边,不能直接被修改。否则会抛出异常。
这时就需要call、apply、bind这三个方法来改变this的指向。

function fn(){
          this=100; //Uncaught SyntaxError: Invalid left-hand side in assignment
          console.log(this);
        }
   fn()

call

call的情况下:

  1. fn的属性名是call的属性值执行,但是fn没有call属性,所以需要通过**proto向原型查找,找到了Function原型中的call**,并且让call函数执行了。
  2. call执行时,改变了fn中的this,让这个this指向call方法第一个实参。(如果不传参或者传入null \ undefined,非严格模式下fnthis指向window)
  3. call中传入的第二个参数及之后的参数,都传给fn这个函数。
 function fn(a,b,){
            console.log(this);// [100,200]
             console.log(a);//  10
             console.log(b);// 11
        }
fn.call([100,200],10,11)

一个参数多次调用call方法(二次及以上):

function fn1() {
           console.log(1)
           console.log(this)
       }
function fn2() {
        console.log(2)
     console.log(this)
 }
 fn1.call(fn2) //  1   ƒ fn2(){}
 fn1.call.call(fn2) //   2   window

我们封装一下call基本的源码:

  1. call
function fn1(a, b) {
            console.log(this) // obj
            console.log(a)   // 11
            console.log(b)  //  12
        }
let obj = { name: "newThis" }
Function.prototype.Mycall = function (obj, ...ary) {
       
            obj = obj || window  //  如果不传参数 就让其指向window
            obj.$fn = this; //  this就是fn1函数
            var result = obj.$fn(...ary);
            delete obj.$fn //  自己添加的属性,最后要清掉,避免影响使用
            return result // 把函数的返回值return出去
        }
 fn1.Mycall(obj, 11, 12)
  1. call
function fn1() {
            console.log(this)
        }
function fn2() {
            console.log(this)
        }
Function.prototype.Mycall = function (arg) {
            arg = arg || window  //  如果不传参数 就让其指向window
            arg.$fn = this; //  this是fn1.Mycall ;  fn1.Mycall就是在fn1中查找属性名为Mycall的属性值 就是Mycall这个方法本身
            var result = obj.$fn(); //相当于fn2.Mycall()  在这把上文单call在走一边,因为没有传参所以fn2中的this指向window
            delete arg.$fn //  自己添加的属性,最后要清掉,避免影响使用
            return result // 把函数的返回值return出去
        }
 fn1.Mycall.Mycall(fn2) //暂不考虑传多个参数的情况

如有不对,欢迎指出问题所在,定当认真修改。
链接: 博客主页.

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值