🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN个人主页
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
文章目录
- 一、引言
- 介绍 call 和 apply 的概念
- 为什么需要 call 和 apply
- 二、 call 和 apply 的语法和参数
- call 和 apply 的语法和参数
- 三、 call 和 apply 的区别
- 调用方式的区别
- 参数传递的区别
- 四、使用 call 和 apply 的场景
一、引言
介绍 call 和 apply 的概念
call
和apply
是JavaScript中的两个方法,它们都可以用来调用函数,并改变函数内部的this
指向。
-
call
的语法为函数名.call(obj,参数1,参数2,参数3……)
,它将函数作为一个方法绑定到指定对象上进行调用,并且将函数内部的this
设置为指定的对象。 -
apply
的语法为函数名.apply(obj,[参数1,参数2,参数3……])
,它与call
类似,但区别在于它将所有参数写在数组里面。
这两个方法的本质都是通过改变对象的内部指针,将特定函数作为一个方法绑定到指定对象上并进行调用。在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用,使用call
或apply
方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。
为什么需要 call 和 apply
在 JavaScript 中,call
和apply
的作用都是在函数调用时改变函数的执行上下文,也就是函数内部的this
。它们的使用场景如下:
- 在函数作为对象方法的情况下,
this
会指向对象。如果需要在调用函数时改变this
的指向,可以使用call
或apply
方法。 - 在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用。使用
call
或apply
方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。
总之,call
和apply
方法可以帮助我们在函数调用时根据需要改变函数的执行环境,从而实现更加灵活和可定制的代码。
二、 call 和 apply 的语法和参数
call 和 apply 的语法和参数
call
和apply
的语法和参数具体如下:
call
方法:- 语法:
call((thisObj(,arg1(, arg2(, (,.argN)))))
- 说明:
- 第一个参数是表示要绑定的对象,如果调用时不传参,比如
call()
、call(null)
、call(undefined)
,那么this
都指向window
对象。 - 传递另一个函数的函数名,那么函数中的
this
指向这个函数的引用。 - 传递字符串、数值或布尔类型等基础类型,那么函数中的
this
指向其对应的包装对象,如String
、Number
、Boolean
。 - 传递一个对象,那么函数中的
this
指向这个对象。
- 第一个参数是表示要绑定的对象,如果调用时不传参,比如
- 语法:
apply
方法:- 语法:
apply((thisObj(,argArray)))
- 说明:
- 如果
argArray
不是一个有效的数组或者不是arguments
对象,那么将导致一个TypeError
。 - 如果没有提供
argArray
和thisObj
任何一个参数,那么Global
对象将被用作thisObj
,并且无法传递任何参数。
- 如果
- 语法:
call
和apply
的作用都是在函数调用时改变函数的执行上下文,也就是函数内部的this
。它们的使用场景如下:
- 在函数作为对象方法的情况下,
this
会指向对象。如果需要在调用函数时改变this
的指向,可以使用call
或apply
方法。 - 在某些情况下,函数可能需要在特定的对象上调用,而不是在全局上下文中调用。使用
call
或apply
方法可以将函数绑定到特定的对象上,以便在调用时能够正确地访问对象的属性和方法。
三、 call 和 apply 的区别
调用方式的区别
call
和apply
的主要区别在于调用方式不同:
call
方法的语法为函数名.call(obj,参数1,参数2,参数3……)
,其中各个参数用逗号分隔。apply
方法的语法为函数名.apply(obj,(参数1,参数2,参数3……))
,其中所有参数写在数组中。
尽管call
和apply
的作用相同,但它们的使用方式略有不同。在实际应用中,可以根据具体需求选择使用哪种方法来调用函数。
参数传递的区别
call
和apply
在参数传递方面也存在一些区别:
call
方法可以传递任意数量的参数,参数之间用逗号分隔。apply
方法需要将参数传递给一个数组,数组中的元素就是要传递的参数。
下面是一个示例,展示了如何使用call
和apply
方法以及它们之间的区别:
function sum(num1, num2) {return num1 + num2;
}// 使用 call 方法
var result1 = sum.call(null, 10, 20);
console.log(result1); // 使用 apply 方法
var result2 = sum.apply(null, [10, 20]);
console.log(result2);
在上述示例中,定义了一个sum
函数,它接收两个参数并返回它们的和。通过调用sum.call(null, 10, 20)
,将null
作为this
值,并传递了两个参数10
和20
给sum
函数。通过调用sum.apply(null, [10, 20])
,同样将null
作为this
值,并将一个包含参数10
和20
的数组传递给sum
函数。
尽管call
和apply
的作用相同,但它们的使用方式略有不同。在实际应用中,可以根据具体需求选择使用哪种方法来调用函数。
四、使用 call 和 apply 的场景
call
和apply
方法主要用于改变对象的上下文,在以下场景中比较常见:
- 改变对象的上下文:可以使用
call
或apply
方法将函数作为另一个对象的方法进行调用,从而改变函数内部this
的值。
var obj1 = {name: 'John',sayHello: function() {console.log('Hello, ' + this.name);}
};var obj2 = {name: 'Alice'
};obj1.sayHello.call(obj2);
在上面的示例中,有两个对象obj1
和obj2
,obj1
有一个名为sayHello
的方法。通过使用call
方法,将obj2
作为this
值传递给sayHello
方法,输出结果将会是Hello, Alice
。
- 实现继承:可以使用
call
或apply
方法来模拟继承。
function Parent() {this.name = 'parent';
}Parent.prototype.sayGoodbye = function() {console.log('Goodbye, ' + this.name);
}function Child() {// 调用父类构造函数,实现属性继承Parent.call(this); this.type = 'child';
}// 子类的原型指向父类的实例,实现方法继承
Child.prototype = Object.create(Parent.prototype);
// 修复构造函数指向问题,确保子类的构造函数指向自己
Child.prototype.constructor = Child; var child = new Child();
child.sayGoodbye();
在上面的示例中,创建了一个父类Parent
和一个子类Child
。通过使用call
方法,在子类的构造函数中调用父类的构造函数,实现属性继承。然后,通过设置子类的原型指向父类的实例,实现方法继承。最后,创建子类的实例,并调用sayGoodbye
方法。
除了上述常见场景外,call
和apply
方法还可以用于其他一些情况,例如在某些框架中进行事件绑定、延迟执行等。具体使用场景取决于具体的需求和代码结构。