javascript中call()、apply()与bind()的区别及实现原理解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u012149969/article/details/98043339
  • 由于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—————
喜欢本文的朋友们,欢迎关注公众号 张培跃,收看更多精彩内容!!!公众号回复 电子书 ,送你经典电子书籍!

猜你喜欢

转载自blog.csdn.net/u012149969/article/details/98043339