apply()与call()的区别
一直都没太明白apply()与call()的具体使用原理,今日闲来无事,决定好好研究一番。
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); //
c2.showAdd(3,1); //
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("","","");
var arr2=new Array("","","");
Array.prototype.push.apply(arr1,arr2); //得到合并后数组的长度,因为push就是返回一个数组的长度
也可以这样理解,arr1调用了push方法,参数是通过apply将数组转换为参数列表的集合
通常在什么情况下,可以使用apply类似Math.max等之类的特殊用法:
一般在目标函数只需要n个参数列表,而不接收一个数组的形式,可以通过apply的方式巧妙地解决这个问题。

apply()与call()的区别的更多相关文章
- 瞬间记住Javascript中apply与call的区别
关于Javascript函数的apply与call方法的用法,网上的文章很多,我就不多话了.apply和call的作用很相似,但使用方式有区别 apply与call的第一个参数都是一个对象,这个对象就 ...
- 改变this指针的apply,call,bind的区别
apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...
- apply()和call()的区别
这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值. apply()接收两个参数:一个参数是在其中运行的作用域,另一个是参数数组(可以是Array实例,也可以是arg ...
- 【JavaScript】apply和call的区别在哪?
我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家 ...
- android SharedPreferences apply和commit的区别
1.apply没有返回值而commit返回boolean表明修改是否提交成功2.apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘3.apply ...
- JavaScript之apply()和call()的区别
我 在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示 例,总算是看的有点眉目了,在这里我做如下笔记,希望和 ...
- JS 中的this指向问题和call、apply、bind的区别
this的指向问题 一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向window. function a(){ console.log(this); //输出函数a中的th ...
- .call() 和 .apply() 的含义和区别
JavaScript中apply与call的用法意义及区别 apply()与call()的区别 javascript中apply和call方法的作用及区别说明 .apply()用法和call()的区别 ...
- apply 和call 的区别,apply实用小技巧
Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
- this+call、apply、bind的区别与使用
http://www.ruanyifeng.com/blog/2018/06/javascript-this.html https://segmentfault.com/a/1190000018017 ...
随机推荐
- iOS UICollectionView基础
转载自:http://www.cnblogs.com/wayne23/p/4013522.html 初始化部分: UICollectionViewFlowLayout *flowLayout= [[ ...
- POJ3273-Monthly Expense (最小化最大值)
题目链接:cid=80117#problem/E">click here~~ [题目大意] 农夫JF在n天中每天的花费,要求把这n天分作m组.每组的天数必定是连续的.要求分得各组的花费 ...
- 【转】linux中的sort命令
转自:http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分 ...
- Swipe2.1更新——移动Web内容滑块
Swipe JS 是一个轻量级(3.7 kb) mobile slider,支持 1:1 触摸移动(基于精确的触摸位置的内容滑动). 但是我使用一段时间后发现两个bug,所以在官方2.0(官网http ...
- 使MySQL 支持繁体字
要 MySQL 支持繁体字,可以将相关编码设置为 UTF8 (也叫 UTF-8).编码的设置从浏览器到表字段,一个都不能少: 浏览器设置 HTML设置 服务器 Request 对象设置 数据库连接设置 ...
- ulimit 命令详解
Linux对于每个用户,系统限制其最大进程数.为提高性能,可以根据设备资源情况,设置各linux 用户的最大进程数 可以用ulimit -a 来显示当前的各种用户进程限制. 下面我把某linux用 ...
- php中body下出现莫名空白字符
php中body下出现莫名空白字符,出现原因 1. 模板前面有莫名格式空格,删不掉,必须把模板里面东西复制出来,新建一个文件弄进去,覆盖原有的 2.docutype前面出现代码,也会导致此问题(有可能 ...
- eclipse @override错误
@Override是JDK5 就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override而JDK6 修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Over ...
- 使用Atomikos Transactions Essentials实现多数据源JTA分布式事务--转载
原文:http://www.ite/topic/122700 9.17 update:使用NonXADataSourceBean. Mysql在5.0版本和Connecter/J5.0版本后提供了XA ...
- 【转】Singleton单例模式
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生成器. ...