js深入突破,this指针问题,实现call的原理,通过原生改变代码逻辑!

1 篇文章 0 订阅
1 篇文章 0 订阅

js深入突破,this指针问题,实现call的原理,通过原生改变代码逻辑!

大致介绍

everyone,这里是小m马的第二次技术分享,关于该如何正确的使用this的指向,来通过自己的逻辑能力来手写一个call的原理,当然这个过程中相信大家也会对call的理解会更深刻,虽然我们平时不用运用到call,但是这个核心的问题是在代开的开发中会经常遇到的,逻辑,this,call,对象,好了,根据这四个关键字,我们进行阅读!

在这里插入图片描述

举个例子!进行对比,首先我们看call的作用

var foo = {
    value:1
}
var bar = function(name,age){
    console.log(name)
    console.log(age)
    console.log(this.value)
}
bar.call(foo,'kewen',18)

//1,kewen,18   打印结果

这段call的原生代码执行出来后会打印出,1,kewen,18 ,接下来进行我们的手写call,仔细观察每一步

var foo = {
    value:1
}
Function.prototype.call2=(context)=>{
    context.fn = this
    var ages = []
    for(let i = 1 ; i<arguments.length;i++){
        //age.push('aguments['+i+']')
         args.push(arguments[i]);
    }
    eval('context.fn('+ages+'')')
    delete context.fn
}
var bar = function(){
    console.log(name)
    console.log(age)
    console.log(this.value)
}
bar.call2(foo,'kewen',18)
// 1,kewen,18

第一步声明一个对象,内有属性value:1,然后可以发现接下来是两个函数,
直接看bar这个函数,打印三个属性,然后是执行了函数bar的方法call2(也就是我们自己通过原型建造的一个函数方法)传递了三个参数
1.foo对象
2.kewen(字符串)
3.18(数字)

接着我们看中间的部分,小m马在bar这个函数的原型中添加了一个叫做call2的方法,这也就是为什么我们可以使用bar.call2(foo,‘kewen’,18)的原因

我们在bar的原型中添加了call2的方法,并且传入了context的参数,也就是foo
接下来是步骤解释:

  1. 给context添加了一个属性fn,值为this,this为call2,而call2其实是bar的原型,所以是指向bar函数的,但是千万记住this的话是谁调用指向谁的
  2. 遍历了arguments添加入空数组,arguments也就是函数的参数,那么有些朋友会疑惑这个call2的参数我们只传递了context为什么我们还要进行遍历,其实不然,我们可以看到在外面我们执行方法时是bar.call2(foo,‘kewen’,18),三个参数,虽然在原型中我们只拿到了context,但是arguments依然会包括其他两个
  3. 执行context.fn,在上面我们交代了,这个this指向了bar的原型函数,那bar没有value为什么可以打印出1来,因为我们把foo.fn 的this指向了bar的属性值call2,所以这call2的this函数领域内是包含了foo的,也就是说foo和call2共享了同一个this,那么就可以解释为什么能打印出1来了,而call2本身的this是可以找到bar的,那么也打印出kewen和18也合情合理了
  4. 至于第三步为什么要删除这个方法,是因为避免不必要垃圾残存和以后带来的影响

注释:至于为什么可以给函数添加一个方法,这是关于原型的知识点,以后小m马会进行解析,希望大家持续关注,如果大家有观点的地方,那是大家对自己理解的方式表达的不同,希望理解!

在这里插入图片描述

解释eval函数的作用

 Function.prototype.call2 = function (context) {
        context.fn = this;
        var args = [];
        for (var i = 1, len = arguments.length; i < len; i++) {
            args.push(arguments[i]);
            //age.push('aguments['+i+']')
        }
        // eval('context.fn(' + args + ')');
        context.fn(...args)
        delete context.fn;
    }

    // 测试一下
    var foo = {
        value: 1
    };

    function bar(name, age) {
        console.log(name)
        console.log(age)
        console.log(this.value);
    }

    bar.call2(foo, 'kevin', 18); 

eval函数,这是一个非常强大的方法,但是一般情况下大家也用不怎么到,大多数情况下用于计算作用,当然执行函数也没有问题,所以我们在 这里使用,就是执行一下bar这个函数,当然这个写法有点让人奇奇怪怪的,所以小m马把他翻译一下

今天分享到此结束,希望大家可以持续关注小m马,小m马每天都在进步,分享硬货js知识,本篇文章在面试的时候和对自己的提升都有很大的作用,再一次感谢大家的观看!!!
这里是小m马,每周的前端硬货分享,大家一起探讨可以私信我!!!
(上一篇博客中说到会对if的优化有升级说明和讲解,我们后面会写出来,是在感到抱歉的是这一次没有进行更新,会补上哦!)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值