apply和call方法
正在找工作,马上要毕业了。在补充js基础方法。
参考博客:http://blog.csdn.net/myhahaxiao/article/details/6952321
这篇博客主要解决三个问题:
1. apply和call的区别在哪里
2. 什么情况下用apply,什么情况下用call
3. apply的其他巧妙用法(一般在什么情况下可以使用apply)
apply和call的定义:
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
2、常用实例
a、js代码块
function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } add.call(sub,3,1);
这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。(其还可以看成是sub继承了add这个方法并调用执行)
b、js代码块
function Animal(){ this.name = "Animal"; this.showName = function(){ alert(this.name); } } function Cat(){ this.name = "Cat"; } var animal = new Animal(); var cat = new Cat(); //通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。 //输入结果为"Cat" animal.showName.call(cat,","); //animal.showName.apply(cat,[]);
call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
c、实现继承 js代码块
function Animal(name){ this.name = name; this.showName = function(){ alert(this.name); } } function Cat(name){ Animal.call(this, name); } var cat = new Cat("Black Cat"); cat.showName();
Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
d、多重继承 js代码块
function Class10()
{ this.showSub = function(a,b) { alert(a-b); }
} function Class11()
{ this.showAdd = function(a,b) { alert(a+b); }
} function Class2()
{ Class10.call(this); Class11.call(this);
}
区分:
很简单,使用两个 call 就实现多重继承了 当然,js的继承还有其他方法,例如使用原型链,这个不属于本文的范畴,只是在此说明call 的用法。说了call ,当然还有 apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments 还有 callee,caller..
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)
call:和apply的意思一样,只不过是参数列表不一样.
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
1. apply示例:
- <script type="text/javascript">
- /*定义一个人类*/
- function Person(name,age)
- {
- this.name=name;
- this.age=age;
- }
- /*定义一个学生类*/
- functionStudent(name,age,grade)
- {
- Person.apply(this,arguments);
- this.grade=grade;
- }
- //创建一个学生类
- var student=new Student("zhangsan",21,"一年级");
- //测试
- alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
- //大家可以看到测试结果name:zhangsan age:21 grade:一年级
- //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.
- </script>
分析: Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“zhangsan”,”21”,”一年级”];
也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面
2. call示例
在Studen函数里面可以将apply中修改成如下:
Person.call(this,name,age);
这样就ok了
3. 什么情况下用apply,什么情况下用call
在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));
4. apply的一些其他巧妙用法
细心的人可能已经察觉到,在我调用apply方法的时候,第一个参数是对象(this), 第二个参数是一个数组集合, 在调用Person的时候,他需要的不是一个数组,但是为什么他给我一个数组我仍然可以将数组解析为一个一个的参数,这个就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) 这个如果让我们用程序来实现将数组的每一个项,来装换为参数的列表,可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法:
a) Math.max 可以实现得到数组中最大的一项
因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组
但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项(apply会将一个数组装换为一个参数接一个参数的传递给方法)
这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去
b) Math.min 可以实现得到数组中最小的一项
同样和 max是一个思想 var min=Math.min.apply(null,array);
c) Array.prototype.push 可以实现两个数组合并
同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即:
- vararr1=new Array("1","2","3");
- vararr2=new Array("4","5","6");
- Array.prototype.push.apply(arr1,arr2);
也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.
通常在什么情况下,可以使用apply类似Math.min等之类的特殊用法:
一般在目标函数只需要n个参数列表,而不接收一个数组的形式([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙地解决这个问题!
apply和call方法相关推荐
- groupby+(apply+agg+transform)方法的比较
groupby+(apply+agg+transform)方法的比较 分组函数groupby+(apply+agg+transform)方法的比较 pandas模块给数据处理的能力给予了很大的助力,但 ...
- JS中的call、apply、bind方法详解
bind 是返回对应函数,便于稍后调用:apply .call 则是立即调用 . apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(co ...
- 转载 SharedPreference.Editor的apply和commit方法异同
转载别人的转载:https://blog.csdn.net/jake9602/article/details/18414841 在android 中存储数据时经常用SharedPreference, ...
- 总结apply和call方法的使用 bind方法 bind方法的使用 函数中的几个成员
总结apply和call方法的使用 <!DOCTYPE html> <html lang="en"> <head><meta charse ...
- 函数的不同的调用方式 函数也是对象 数组的函数调用 apply和call方法的使用
函数的不同的调用方式 <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...
- JavaScript的call,apply和bind方法之间的区别
by Rajat Saxena 通过拉贾特·萨克森纳(Rajat Saxena) JavaScript的call,apply和bind方法之间的区别 (The difference between J ...
- 理解 call、apply、bind 原理,手写简单的 call、apply、bind 方法
理解 call.apply.bind 原理,手写简单的 call.apply.bind 方法 call 原理及实现 MDN定义:call()方法使用给定的 this 值和单独提供的参数调用函数. 用自 ...
- 前端学习辑录(3):apply,call,bind方法总结
目录 apply,call,bind方法总结: 1.apply()方法 2.call()方法 3.bind()方法 总结 apply,call,bind方法总结: 1.apply()方法 apply的 ...
- 优雅的理解 call 和 apply 的使用方法
作者在看到一篇优雅的使用 js 的各种方法解决算法的时候产生的疑问,到底什么时候使用 apply 和 call 啦? 每次看到别人用 apply 和 call 其实从以前的懵懵懂懂到现在的明白,但是自 ...
最新文章
- Windows安全策略
- TensorFlow实现卷积、池化操作
- Jupyter notebook 使用多个Conda 环境
- Java 算法 新生舞会
- C语言 底层IO openclose
- CentOS下使用Varnish为网站加速
- delphi7 获取dll的类_上传quot;定时任务quot;获取系统权限
- python 桌面数据库_python数据库操作笔记
- Intel i5-7200U (3100MHZ),1*8GB(DDR4 2666) 在 Aida64 V5.97.4600 的测试结果
- 获取当前时间戳的方法
- RTT移植STM32之创建进程
- 电机与拖动综合控制实验matlab,电机与拖动基础及MATLAB仿真
- WIN2K XP 2K3 下红警不能联机的完美解决方案(转)
- vue3中的vue-router简单实现以及router变迁带来的思考
- Mac SpotLight无法搜索
- 猿辅导python大纲_数据解读独角兽企业“猿辅导”(第一部分)
- S700K表示电路速查【铁路信号技术专栏】转自微信公众号铁路信号技术交流
- 最短路(hdu2544,floyd最短路)
- 基于Opencv的颜色识别
- Total Bummer:透​​视水滴