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

本文详细解析了JavaScript中call、apply及bind方法的功能与区别,包括它们如何改变函数内部的this指向,以及各自的实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一, call、apply、bind异同:

  • 由于**call()、apply()与bind()**都是属于Function.prototype对象下的方法,所以每个function实例都拥有有call、apply与bind属性。
  • 相同点:都是为改变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: "bugcheng@163.com"
}
function printSiteName() {
    console.log(this.siteName);
}
var site = printSiteName.mybind(obj);
// 返回的是一个函数
console.log(site) // function () {}
// 通过mybind使其this发生了变化
site();// bugcheng@163.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值