• 深入理解javascript中bind、apply、call


    相信做过一段时间的javascript开发的同学都或多或少用过或者见到过bind、apply、call方法。他们的作用很简单,就是改变执行函数的this指向,如果您对this了解比较模糊,您可以看这一篇博客

    作用

    首先,我们了解下,改变执行函数的this指向有哪些作用,对我们开发有哪些好处。同样,我们从一个例子开始吧。

    const obj = {
        name: '张三',
        age: 18,
        introduction: function() {
            console.log(`my name is ${this.name}, i am ${this.age} years old`)
        }
    }
    
    obj.introduction(); //my name is 张三, i am 18 years old
    
    obj.introduction.apply({name: '李四', age: 22}); //my name is 李四, i am 22 years old

    例子中,张三有一个introduction可以介绍他的信息,所以当调用obj.introduction()时,可以打印张三的个人信息,后面,我们将obj.introduction()方法绑定在了对象{name: '李四', age: 22}上,从而改变了this指向,最终打印了李四的个人信息。

    由此,我们可以看出通过改变this指向,我们可以实现代码复用。

    异同

    了解了改变this指向的作用后,我们发现bind、apply、call都是可以改变this指向,那它们有何不同之处呢,下面我们讨论下。

    1. bind

    bind方法第一个参数是需要绑定的对象,后面的参数是改变this指向方法的参数,值得注意的是bind方法的返回值仍然是一个方法,我们需要添加一对小括号才能让他执行。请看使用实例。

    const obj = {
        name: '张三',
        age: 18,
        introduction: function(sex) {
            console.log(`my name is ${this.name}, i am ${this.age} years old, my sex is ${sex}`)
        }
    }
    
    const bindFunc = obj.introduction.bind({name: '王五', age: 21}, 'men');
    bindFunc(); //my name is 王五, i am 21 years old, my sex is men

    2.  apply

    apply方法第一个参数是需要绑定的对象,第二个参数是一个数组,数组中的元素为改变this指向方法的参数,和bind不同的是,此时函数会立即执行。请看实例。

    const obj = {
        name: '张三',
        age: 18,
        introduction: function(sex) {
            console.log(`my name is ${this.name}, i am ${this.age} years old, my sex is ${sex}`)
        }
    }
    obj.introduction.apply({name: '李四', age: 22}, ['men']); //my name is 李四, i am 22 years old, my sex is men

    3. call

    call方法和apply方法极为相似,方法第一个参数是需要绑定的对象,后面的参数是改变this指向方法的参数,同样,函数也是立即执行。请看实例。

    const obj = {
        name: '张三',
        age: 18,
        introduction: function(sex) {
            console.log(`my name is ${this.name}, i am ${this.age} years old, my sex is ${sex}`)
        }
    }
    
    obj.introduction.call({name: '周六', age: 19}, 'men'); //my name is 周六, i am 19 years old, my sex is men

    关于他们的异同,这里总结了一个表格。 

    相信了解他们的用法是一个比较简单的事儿。不过,作为一个励志成为一个更优秀(tutou)的程序yuan,刨根问底是一个优良品质。

    下面,我们来分别实现这三个方法。

    1. myBind

    程序实现

    function myBind(ctx, ...rest) {
        const context = ctx || window;
        const _this = this;
    
        return function() {
            context.fn = _this;
            context.fn(...rest);
            delete context.fn;
        }
    }
    
    Function.prototype.myBind = myBind;

    2. apply

    程序实现

    function myApply(ctx, params) {
        const context = ctx || window;
    
        ctx.fn = this;
        ctx.fn(...params);
        delete ctx.fn;
    }

      Function.prototype.myApply = myApply;

    3. call

    程序实现

    function myCall(ctx, ...rest) {
        const context = ctx || window;
    
        context.fn = this;
        context.fn(rest);
        delete context.fn;
    }
    Function.prototype.myCall = myCall;

    相信上面的代码聪明的你一眼就看懂了。bind、call、apply三个方法的实现原理都是一样的,只是让我们可以通过不同的方式使用它。

    他们改变this指向的原理是通过 将需要改变this指向的方法附加在对象中执行,则方法中的this就会指向附加的对象。(在方法中,this 表示该方法所属的对象。)

    浅陋见识,不足之处,请大神指正。

  • 相关阅读:
    初识反射
    eclipse简单使用
    常见的原生javascript DOM操作
    你知道CSS实现水平垂直居中的第10种方式吗?
    localStorage 存满了怎么办?
    localStorage使用总结
    js中利用cookie实现记住密码功能
    利用PHP将图片转换成base64编码的实现方法
    php获得可靠的精准的当前时间 ( 通过授时服务器 )
    校正PHP服务器时间不准的问题
  • 原文地址:https://www.cnblogs.com/heshuaiblog/p/13996652.html
Copyright © 2020-2023  润新知