JavaScript中call、apply和bind方法的异同与实战

作者:半夏

时间:2026-10-30

浏览:465

本文通过具体实例深入解析JavaScript中call、apply和bind三个方法的用法与区别。三者均可改变函数执行时的this指向,但call和apply会立即执行函数,而bind返回新函数供后续调用。此外,它们在参数传递方式上存在差异:call接受离散参数,apply要求第二个参数为数组,bind支持预置参数并在调用时追加。

文章目录

JavaScript中call、apply和bind方法的异同与实战

本文通过具体代码示例,详细解析JavaScript中call、apply和bind三个方法的用法与区别,供读者参考学习。


<!DOCTYPE html>
<html>

 <head>
 <meta charset="UTF-8">
 <title></title>
 <script type="text/javascript">
  function MAN(name, sex, age) {
  this.name = name;
  this.sex = sex;
  this.age = age;
  this.say = function(school,zhuanye) {
   console.log(this.name + " , " + this.sex + " ,今年" + this.age+"岁!在"+school+"学习"+zhuanye);
  }
  }
  function WOMAN(name, sex, age) {
  this.name = name;
  this.sex = sex;
  this.age = age;
  }
  var man=new MAN("张三","男",26);
  var woman=new WOMAN("小红","女",18);
  man.say('清华大学','挖掘机');
  man.say.call(woman,"蓝翔技校","电气焊");
  man.say.apply(woman,["新东方","火星语"]);
  man.say.bind(woman)("德云社","流行音乐");
 </script>
 </head>

 <body>
 </body>

</html>

JavaScript中call、apply和bind方法的异同与实战

为什么需要掌握call、apply和bind

为什么要学习这三个方法?它们主要解决什么问题?

这三个方法的核心作用是指定函数执行时的this环境。在掌握它们之前,开发者常遇到this指向不明确导致的bug。


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user);
  }
}
var b = a.fn;
b(); //undefined

例如,试图打印对象a中的user属性却返回undefined,这是因为直接调用a.fn()时this指向正确,但将函数赋值给其他变量后调用,this指向会丢失。


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user);
  }
}
a.fn(); //追梦子

直接执行a.fn()能正常打印,是因为此时this明确指向对象a。若需深入理解this的指向规则,建议参考关于JavaScript中this指向的详细解析文章,避免死记硬背。

虽然直接调用可行,但有时我们需要将对象保存到其他变量中再调用,此时可通过特定方法恢复正确的this指向。

call方法详解

1、call()方法


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user); //追梦子
  }
}
var b = a.fn;
b.call(a);

使用call方法时,第一个参数用于指定函数执行时的this指向对象。简单来说,传入哪个对象,this就指向哪个对象。除了第一个参数外,call还可以接收多个后续参数,具体用法如下:


var a = {
  user:"追梦子",
  fn:function(e,ee){
    console.log(this.user); //追梦子
    console.log(e+ee); //3
  }
}
var b = a.fn;
b.call(a,1,2);

apply方法详解

2、apply()方法

apply方法与call类似,同样可以改变函数执行时的this指向。


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user); //追梦子
  }
}
var b = a.fn;
b.apply(a);

apply也可以接收多个参数,但其关键区别在于:第二个参数必须是一个数组(或类数组对象),用于传递函数所需的参数列表,示例如下:


var a = {
  user:"追梦子",
  fn:function(e,ee){
    console.log(this.user); //追梦子
    console.log(e+ee); //11
  }
}
var b = a.fn;
b.apply(a,[10,1]);

或者采用数组直接传递的方式:


var a = {
  user:"追梦子",
  fn:function(e,ee){
    console.log(this.user); //追梦子
    console.log(e+ee); //520
  }
}
var b = a.fn;
var arr = [500,20];
b.apply(a,arr);


//注意如果call和apply的第一个参数写的是null,那么this指向的是window对象

var a = {
  user:"追梦子",
  fn:function(){
    console.log(this); //Window {external: Object, chrome: Object, document: document, a: Object, speechSynthesis: SpeechSynthesis…}
  }
}
var b = a.fn;
b.apply(null);

bind方法详解

3、bind()方法

bind方法与call、apply在功能上有相似之处,即都能改变this的指向,但它们的执行机制和返回值不同。

首先来看它们的主要区别:


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user);
  }
}
var b = a.fn;
b.bind(a);

执行上述代码时,函数体并未立即打印输出。这是因为bind与call、apply不同,它不会立即执行原函数,而是返回一个修改了this指向的新函数。


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user);
  }
}
var b = a.fn;
var c = b.bind(a);
console.log(c); //function() { [native code] }

接下来,我们调用这个由bind返回的新函数c,观察是否能正确打印出对象a中的user属性。


var a = {
  user:"追梦子",
  fn:function(){
    console.log(this.user); //追梦子
  }
}
var b = a.fn;
var c = b.bind(a);
c();

同样,bind也支持多个参数。它允许在绑定预置参数的基础上,在最终调用时追加参数。需要注意的是,追加的参数会按照原函数形参的顺序进行匹配和传递。


var a = {
  user:"追梦子",
  fn:function(e,d,f){
    console.log(this.user); //追梦子
    console.log(e,d,f); //10 1 2
  }
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);

三者区别总结

总结:call和apply都会改变上下文中的this并立即执行函数;而bind方法返回一个新函数,允许在需要时再调用,且支持在绑定阶段预置参数,在调用阶段追加参数。开发者可根据实际场景选择合适的方法。

以上就是本文的全部内容,希望有助于大家的学习,欢迎继续支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章