美文网首页Web前端之路JavaScript 进阶营
javascript中call()、apply()与bind()

javascript中call()、apply()与bind()

作者: 张培跃 | 来源:发表于2019-08-01 11:45 被阅读28次
    • 由于call()apply()bind()都是属于Function.prototype对象下的方法,所以每个function实例都拥有有callapplybind属性。
    • 相同点:都是为改变this指向而存在的
    • 异同点:使用call()方法时,传递给函数的参数必须逐个列举出来,使用apply()方法时,传递给函数的是参数数组。bind()call()很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。bind() 方法不会立即执行,而是返回一个改变了上下文 this后的函数,用于稍后调用。 call()apply()则是立即调用。
    1、call实现原理:
    Function.prototype.mycall = function (context) {
        // 当context为null时,其值则为window
        context = context || window;
        // this为调用mycall的函数。将this赋值给context的fn属性
        context.fn = this;
        // 将arguments转为数组,并从下标1位置开如截取
        let arg = [...arguments].slice(1);
        // 将arg数组的元素作为fn方法的参数执行,结果赋值给result
        let result = context.fn(...arg);
        // 删除fn属性
        delete context.fn;
        // 返回结果
        return result;
    }
    

    测试:

    function add(c, d){
        return this.a + this.b + c + d;
    }
    var obj = {a:1, b:2};
    console.log(add.mycall(obj, 3, 4)); // 10
    
    2、apply实现原理
    Function.prototype.myapply = function (context) {
        // 当context为null时,其值则为window
        context = context || window
        // this为调用myapply的函数。将this赋值给context的fn属性
        context.fn = this;
        // 如果未传值,则为一空数组
        let arg = arguments[1] || [];
        // 将arg数组的元素作为fn方法的参数执行,结果赋值给result
        let result = context.fn(...arg);
        // 删除fn属性
        delete context.fn
        // 返回结果
        return result
    }
    
    测试:
    function add(c, d){
        return this.a + this.b + c + d;
    }
    var obj = {a:1, b:2};
    console.log(add.myapply(obj, [5, 6])); // 14
    
    3、bind实现原理
    Function.prototype.mybind = function (context) {
        // this为调用mybind的函数。将this赋值给变量_this
        let _this = this;
        // 将arguments转为数组,并从下标1位置开如截取
        let arg = [...arguments].slice(1);
        // 返回函数fn
        return function fn(){
            // 通过apply方法调用函数并返回结果。
            return _this.apply(context, arg.concat(...arguments));
        }
    }
    

    测试:

    var obj = {
        siteName: "zhangpeiyue.com"
    }
    function printSiteName() {
        console.log(this.siteName);
    }
    var site = printSiteName.mybind(obj);
    // 返回的是一个函数
    console.log(site) // function () { … }
    // 通过mybind使其this发生了变化
    site();// zhangpeiyue.com
    

    —————END—————
    喜欢本文的朋友们,欢迎关注公众号 张培跃,收看更多精彩内容!!!公众号回复 电子书 ,送你经典电子书籍!

    相关文章

      网友评论

        本文标题:javascript中call()、apply()与bind()

        本文链接:https://www.haomeiwen.com/subject/qvlqdctx.html