JavaScript:浅谈函数调用call()、apply()、bind()

本文深入探讨JavaScript中的call、apply和bind方法,它们用于改变函数执行时的上下文(this)指向。call和apply在作用上相同,但参数传递方式不同,call接收有序参数,apply接收参数数组。bind则创建新函数,保持指定的this值和参数列表。通过示例展示了如何使用这些方法找到数组的最大值和最小值,以及在事件绑定中应用bind确保正确的上下文。最后比较了三者之间的区别:apply和call用于立即执行,bind返回新函数以延迟执行。

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

立即调用(call now)

javascript中,callapply都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

区别:作用一样,接受参数的方式不一样
其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

例如有一个函数定义如下

let fun = function(arg1,arg2){}
call()

传参

fun.call(this,arg1,arg2)
apply()

传参

fun.apply(this,[arg1,arg2])
实例demo

获取数组中的最大值和最小值

var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers),   //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
  • PS:number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。
新建函数(new function)
bind()

bind()方法创建一个新的函数,在bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

  • 在Javascript中,多次 bind() 是无效的。
let a = function(){}
let b = a
console.log(a==b); // true
            
let c = a.bind() // 新复制的函数,所以会和原来的不一样
console.log(a==c); // false
 

通常我们会使用 _this , that,self 等保存 this `,这样我们可以在改变了上下文之后继续引用到它。

例如这样:

var foo = {
    num: 1,
    change: function(){
        let_this = this;
        $('.btn').on('click',function(event) {
            console.log(_this.num);     //1
        });
    }
}

如果不使用常量保存this的话,this将会指向window而不是foo函数。

可以使用bind()更加优雅的解决这个问题

var foo = {
    num: 1,
    change: function(){
        $('.btn').on('click',function(event) {
            console.log(this.num);      //1
        }.bind(this));
    }
}

在上述代码里,bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文this(其实就是 foo ),到 bind() 函数中。然后,当回调函数被执行的时候, this 便指向 foo 对象。

demo

let bar = function(){
	console.log(this.x);
}
letfoo = {
	x:3
}
bar(); // undefined
bar.bind(foo)(); // 3

这里我们创建了一个新的函数 func,当使用 bind()创建一个绑定函数之后,它被执行的时候,它的this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

call、apply、bind比较

demo1:

var obj = {
    x: 81,
};
 
var foo = {
    getX: function() {
        return this.x;
    }
}
 
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

三个输出的都是81,但是注意看使用 bind()方法的,他后面多了对括号。

也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind()方法。而 apply/call则会立即执行函数。

总结:
1、apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
2、apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
3、apply 、 call 、bind 三者都可以利用后续参数传参;
4、bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值