JavaScript中call、apply和bind方法的异同与实战
本文通过具体实例深入解析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>

为什么需要掌握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方法返回一个新函数,允许在需要时再调用,且支持在绑定阶段预置参数,在调用阶段追加参数。开发者可根据实际场景选择合适的方法。
以上就是本文的全部内容,希望有助于大家的学习,欢迎继续支持本站。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
相关标签:
