Call Apply Bind 三者有什么区别

Call Apply Bind 以及this的讲解

对于上述三个方法,我们分为三步来讲
1.复习this指针
2.怎么改变this
3.原理是什么

**

一. 复习this指针

**

先来几道题目,来熟悉下this
(1)下面的代码输出的内容是?

var uName = '张三';
    function a() {
        var uName = "李四";
        console.log(this.uName);
        console.log(this);
    }
    a();

这道题很明显,this.name 并没有具体的调用者,所以默认为 window,这里就要总结一个知识点,
就是 this指针指向的是调用他的对象

输出结果为
张三
window

(2)那我再稍微改变一下

var uName = '张三';
    var a = {
        uName: '李四',
        fun: function (){
            console.log(this.uName);
        }
    }
    a.fun();
    window.a.fun()
    

根据之前总结的知识点,谁调用,指向谁,这里执行的是 a.fun(),是 a 调用,所以指向 a中的内容;
而 window.a.fun() 虽然看上去有些怪,但是本质上是没有变的,依然是 a 调用,不管前面有几个调用者,
指针指向的是最后一个调用者

输出结果为
李四
李四

(3)输出的结果是什么?

var uName = '张三';
    var obj = {
        uName: '李四',
        fun: function (){
            console.log(this.uName);
        }
    }
    var obj2 = obj.fun;
    
    obj2();

这段代码的意思是,把这个函数给到一个变量身上,而这个函数并没有立即执行,随后再通过这个变量去执行(也叫地址引用),根据之前总结的结果,这里并没有出现调用者,this默认指向window

输出的结果为
张三

(4)最后一题

var name = '张三';
    function fun() {
        var uName= '李四';
        fuck();
        function fuck() {
            console.log('执行了',this.uName);
        }
    }
    fn();

很显然,不管是外部的 fn(),还是里面的 fuck(),我们只要清楚,它到底有没有调用者,有么?都没有,所以答案就很清楚了

输出的结果为
张三

**

二.如何改变指针

**

1.使用箭头函数(这个最简单干脆,我反正挺爱用)
这里我就不费篇幅去解释什么是箭头函数了,建议大家去MDN看看,这里留个链接
MDN 关于箭头函数的解释

话不多说,直接上代码!!!

var name = 'A';
    var a = {
        name: 'B',
        fun1: function (){
            console.log(this.name)
        },
        fun2: function (){
            setTimeout(function (){
                this.fun1()
            },2000)
        }
    }
    a.fun2();

这段代码您先甭着急跟着写,你不觉得放在上面很有问题么,fun2中的this指向的是哪?是window,既然都指向window了,那我写this.fun1(),那我上哪去找fun1?直接就找不到,所以,我们下面就使用箭头函数来解决这个问题,上代码

var name = 'A';
    var a = {
        name: 'B',
        fun1: function (){
            console.log(this.name)
        },
        fun2: function (){
            setTimeout(() => {
                this.fun1()
            },2000)
        }
    }
    a.fun2();

现在可以放心的复制这段代码了,这次一执行,有结果了,this指向的是 a。

2.闭包
闭包也算是面试中,比较有戏份的角色了,既然要用,那就要了解什么是闭包
这里依旧是不再这里废话,建议大家多自己动动手,这里就直接给网址
MDN 关于闭包的描述

上代码

var name = 'A';
    var a = {
        name: 'B',
        fun1: function (){
            console.log(this.name);
        },
        fun2: function (){
            //通过变量把外边的指针保存进来,也叫闭包
            var _this = this;
            setTimeout(function (){
                _this.fun1();
            },1000);
        }
    }
    a.fun2();

那既然用箭头函数或者闭包就能解决的问题,为何还要用call 和 apply? 因为它们可以动态的改变,比起箭头函数和闭包更为灵活,call、bind、apply都是重定义this的

为了方便理解,这里还是用代码来解释

var name = 'A',
        age = 20;
    var obj = {
        name: 'B',
        fun: function (){
            console.log(this.name + '/' + this.age)
        }
    }
    var stu = {
        name: 'C',
        age: 25
    }

    obj.fun.call(stu);
    obj.fun.apply(stu);
    obj.fun.bind(stu)();

在实际敲的时候,发现只有bind()方法是需要在后面加()才可以执行,也就是说bind()方法返回的是个函数,需要调用才能执行

不仅在调用上有区别,在三者传参的方式上也是有差异的,这里也是直接上代码来加深理解

var name = 'A',
        age = 20;
    var obj = {
        name: 'B',
        fun: function (industry,skill){
            console.log('我叫' + this.name + '今年' + this.age + '岁,从事' +
                industry + '行业,熟悉' + skill + '技术!')
        }
    }
    var stu = {
        name: 'C',
        age: 25
    }

    obj.fun.call(stu,'计算机','React');
    obj.fun.apply(stu,['计算机','VUE']);
    obj.fun.bind(stu,'计算机','TypeScript')();
    obj.fun.bind(stu,['计算机','Nodejs'])();

通过代码,很容易就看出者三者的区别,call()的参数是直接传递的,apply()的参数需要放在数组里面,bind()则同时拥有两种传参方式,除了返回的是个函数。

总结:

共同点:
1.这三个方法都是Function原型上面的方法,都是针对函数而言的
2.三种方法都是用于改变函数内部this指向的,再严谨点,都是在改变函数执行时=时候的内部this指向
3.都能接收多个参数,第一个参数就是改变后this的指向,后面是可选参数

不同点:
1.apply() 和 call()调用时,会立即返回函数执行结果,它们的this会指向第一个参数,apply()的第二个参数是一个数组,call()的第二个或之的参数都是数组元素
2.bind()方法不会立即调用,而是返回一个新的函数,也叫绑定函函数,其内部的this指向为它传入时的第一个参数,而传入bind()之后的参数作为原函数的参数来调用原函数

以上都是个人在自学是,查阅和观看其他大佬,以及文档之后浅显的总结出来的,其中涉及的一些底层原理,我本人也不是很清楚,我也在虚心的学习中,而发布文章也是为了记录自己的学习心得,望大佬们对其中的错误和不足提出宝贵意见(狗头.jpg)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值