JavaScript 中 call 和 apply 用来调用函数, 那么 call 和 apply 的区别是什么? 下面本篇文章就来给大家介绍一下 call 和 apply 的区别, 希望对大家有所帮助.
JavaScript 中的每一个 Function 对象都有一个 apply() 方法和一个 call() 方法, 它们的语法分别为:
- /*apply() 方法 */
- function.apply(thisObj[, argArray])
- /*call() 方法 */
- function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
它们各自的定义
apply: 调用一个对象的一个方法, 用另一个对象替换当前对象. 例如: B.apply(A, arguments); 即 A 对象应用 B 对象的方法.
call: 调用一个对象的一个方法, 用另一个对象替换当前对象. 例如: B.call(A, args1,args2); 即 A 对象调用 B 对象的方法.
## 它们的共同之处:
都 "可以用来代替另一个对象调用一个方法, 将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象".
它们的不同之处
apply: 最多只能有两个参数 -- 新 this 对象和一个数组 argArray. 如果给该方法传递多个参数, 则把参数都写进这个数组里面, 当然, 即使只有一个参数, 也要写进数组里. 如果 argArray 不是一个有效的数组或 arguments 对象, 那么将导致一个 TypeError. 如果没有提供 argArray 和 thisObj 任何一个参数, 那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数.
call: 它可以接受多个参数, 第一个参数与 apply 一样, 后面则是一串参数列表. 这个方法主要用在 JS 对象各方法相互调用的时候, 使当前 this 实例指针保持一致, 或者在特殊情况下需要改变 this 指针. 如果没有提供 thisObj 参数, 那么 Global 对象被用作 thisObj.
实际上, apply 和 call 的功能是一样的, 只是传入的参数列表形式不同.
示例
(1) 基本用法
- function add(a,b){
- return a+b;
- }
- function sub(a,b){
- return a-b;
- }
- var a1 = add.apply(sub,[4,2]); //sub 调用 add 的方法
- var a2 = sub.apply(add,[4,2]);
- alert(a1); //6
- alert(a2); //2
- /*call 的用法 */
- var a1 = add.call(sub,4,2);
(2) 实现继承
- function Animal(name){
- this.name = name;
- this.showName = function(){
- alert(this.name);
- }
- }
- function Cat(name){
- Animal.apply(this,[name]);
- }
- var cat = new Cat("咕咕");
- cat.showName();
- /*call 的用法 */
- Animal.call(this,name);
(3) 多重继承
- function Class10(){
- this.showSub = function(a,b){
- alert(a - b);
- }
- }
- function Class11(){
- this.showAdd = function(a,b){
- alert(a + b);
- }
- }
- function Class12(){
- Class10.apply(this);
- Class11.apply(this);
- // Class10.call(this);
- //Class11.call(this);
- }
- var c2 = new Class12();
- c2.showSub(3,1); //2
- c2.showAdd(3,1); //4
apply 的一些其他巧妙用法
(1)Math.max 可以实现得到数组中最大的一项
因为 Math.max 不支持 Math.max([param1,param2]) 也就是数组, 但是它支持 Math.max(param1,param2...), 所以可以根据 apply 的特点来解决 var max=Math.max.apply(null,array), 这样就轻易的可以得到一个数组中的最大项 (apply 会将一个数组转换为一个参数接一个参数的方式传递给方法)
这块在调用的时候第一个参数给了 null, 这是因为没有对象去调用这个方法, 我只需要用这个方法帮我运算, 得到返回的结果就行, 所以直接传递了一个 null 过去.
用这种方法也可以实现得到数组中的最小项: Math.min.apply(null,array)
(2)Array.prototype.push 可以实现两个数组的合并
同样 push 方法没有提供 push 一个数组, 但是它提供了 push(param1,param2...paramN), 同样也可以用 apply 来转换一下这个数组, 即:
- var arr1=new Array("1","2","3");
- var arr2=new Array("4","5","6");
- Array.prototype.push.apply(arr1,arr2); // 得到合并后数组的长度, 因为 push 就是返回一个数组的长度
也可以这样理解, arr1 调用了 push 方法, 参数是通过 apply 将数组转换为参数列表的集合
通常在什么情况下, 可以使用 apply 类似 Math.max 等之类的特殊用法:
一般在目标函数只需要 n 个参数列表, 而不接收一个数组的形式, 可以通过 apply 的方式巧妙地解决这个问题
其实看上面两张图打印的结果不难发现, 我们的 apply 和 call 的第一个参数位置就是调用者, 假如 arr1 在第一个参数位置, 就是 arr1 调用了 xxxx, 那么相当于 arr1 此时拥有了 xxx 的方法, 我们举个例子, 例如 Array.prototype.push.apply(arr1,arr2) 就是 arr1 调用了 Array.prototype.push 方法
更多 web 前端 https://www.html.cn/ 知识, 请查阅 HTML 中文网 !!
来源: http://www.css88.com/qa/javascript/17847.html