0
点赞
收藏
分享

微信扫一扫

详解call、bind、apply的作用和区别、手写bind

booksmg2014 2022-04-13 阅读 66

一、call、bind、apply的作用

改变函数执行时的上下文,即改变this指向

永远记住一句话:this永远指向最后调用它的对象

来!念三遍!this永远指向最后调用它的对象!this永远指向最后调用它的对象!this永远指向最后调用它的对象!

二、call、bind、apply三者区别

①call()方法接受参数表列,传递参数arg1,arg2,arg3;apply必须是数组

②call、apply会调用函数并且改变内部this指向;bind不会调用函数也可以改变内部this指向,需要手动调用。

三、call、bind、apply的应用场景

①call传递引用类型、传递值经常用于父类继承

②apply经常跟数组有关系,可以借助于数学对象实现数组的最大值和最小值。

③bind不调用函数,需要手动调用,可以改变this指向比如定时器内部this指向。

四、call()方法

//语法
fun.call(thisArg,arg1,arg2,arg3,...)

call主要用于继承

    function Father(firstName, character) {
        this.firstName = firstName;
        this.character = character;
    }

    function Son(firstName, character) {
        Father.call(this, firstName, character)
    }
    var son = new Son('wang', 'good');
    console.log(son)

在这里插入图片描述

五、apply()方法

//语法 
//第一个参数在fun函数运行时指定的this值 第二个参数只能传递数组 返回值是函数的返回值,因为它调用函数
fun.apply(thisArg, [argsArray])

求数组的最大值

    const arr = [1, 22, 34, 23, 56, 66]
    const max = Math.max.apply(Math, arr)
    console.log(max)

在这里插入图片描述

六、bind()方法

bind()不会调用函数,但可以改变this内部指向

//语法
//fun.bind(thisArg, arg1, arg2, ...)
//返回由指定的this值和初始化参数改造的原函数拷贝
    var myName = {
        name: 'gaby'
    }

    function fn() {
        console.log(this)
    }
    var f = fn.bind(myName);
    f()

在这里插入图片描述

七、手写bind

(1)隐式原型Function.prototype.bind
    Function.prototype.bind = function () {
        //Todo Something
    }
(2)bind的第一个形参是要绑定给函数的上下文
    Function.prototype.bind = function (context) {
        var fn = this;
        return function () {
            return fn.apply(context)
        }
    }

bind函数可以传递多个参数,第一个参数要绑定给调用它的函数上下文,其他的参数将会作为预设参数传递给这个函数

    let foo = function () {
        console.log(arguments);
    }
    foo.bind(null, "a", "b")("c", "d", "e");

在这里插入图片描述

(3)bind返回值绑定改进
    Function.prototype.bind = function (context, ...args) {
        var fn = this;
        return function (...rest) {
            return fn.apply(context, [...args, ...rest])
        }
    }
(4)ES5写法
    Function.prototype.bind = function () {
        var args = Array.prototype.slice.call(arguments)
        var context = args.slice(0, 1)[0];
        var fn = this;
        return function () {
            let rest = Array.prototype.slice.call(arguments);
            return fn.apply(context, arg.concat(rest));
        }
    }
(5)保留函数原型
    Function.prototype.bind = function () {
        var args = Array.prototype.slice.call(arguments)
        var context = args.slice(0, 1)[0];
        var fn = this;
        var res = function () {
            let rest = Array.prototype.slice.call(arguments);
            return fn.apply(context, args.concat(rest));
        }
        if (this.prototype) {
            res.prototype = this.prototype;
        }
        return res;
    }
举报

相关推荐

0 条评论