对apply和call的理解
存在的原因:
call和apply是为了动态改变this而出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。
call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。
因为 JavaScript 的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
两者区别:
var func1 = function(arg1, arg2) {};
就可以通过 func1.call(this, arg1, arg2); 或者 func1.apply(this, [arg1, arg2]); 来调用。其中 this 是你想指定的上下文,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时,用 call;而不确定的时候,用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来便利所有的参数。
举例:
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这样domNodes就可以应用Array下的所有方法了。
function cat(){
}
cat.prototype={
food:"fish",
say: function(){
alert("I love "+this.food);
}
}var blackCat = new cat;
blackCat.say();
如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);
举例引自知乎。
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
常用实例
a、
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
} add.call(sub,,);
这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
b、
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、实现继承
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();
d、多重继承
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和call的理解的更多相关文章
- js 关于apply和call的理解使用
关于call和apply,以前也思考良久,很多时候都以为记住了,但是,我太难了.今天我特地写下笔记,希望可以完全掌握这个东西,也希望可以帮助到任何想对学习这个东西的同学. 一.apply函数定义与理解 ...
- 关于JS中apply方法的基本理解
最近研究OpenLayers源码时,发现其中使用了比较多的apply方法,对其也是很不明白.于是上网经过多方面了解以及自己细细体会后,终于算是基本明白是其干什么的了,这里分享下.apply方法的造型是 ...
- 对call() apply() 方法的简单理解
真的是非常简单的理解,我知道的并不多,在网上查找了很多的资料,还是只能了解一点皮毛,下面来整理出来,方便以后深入的去学习,也是对目前知道的知识点的巩固. 整理一些网上的经典解答: 1.一句话区分cal ...
- 前端基础:call,apply,bind的的理解
背景 前两天在做小程序的需求的时候用到bind的时候才想起自己对这三的东西的了解比较浅薄,这个时候用的时候就有点怕.时候还是要好好学习下,理解下怎么玩. 正文 先说call 和 apply吧:ECMA ...
- call、apply与bind在理解
call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. fun.call(thisArg[, arg1[, arg2[, ...]]]) apply() 方法 ...
- 对于call,apply,bind 的理解
JavaScript 中 call().apply().bind() 的用法 之前对与JavaScript中的call,apply,bind这几个方法一直理解的很模糊,今天总结一下. 例1 var n ...
- JS中的apply,call,bind深入理解
在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...
- js call apply bind简单的理解
相同点:JS中call与apply方法可以改变某个函数执行的上下文环境,也就是可以改变函数内this的指向.区别:call与apply方法的参数中,第一个参数都是指定的上下文环境或者指定的对象,而ca ...
- 学习前端的菜鸡对JS的call,apply,bind的通俗易懂理解
call,apply,bind 在JavaScript中,call.apply和bind是Function对象自带的三个方法,都是为了改变函数体内部 this 的指向. a ...
随机推荐
- 把centos 的mysql 重装一下 把原来的lnmp删除,怎么备份还原数据库
mysqldump --lock-all-tables -u root -p --databases mydb > /opt/database/mydb.sql,或者直接备份mysql的数据存储 ...
- 关于java MulticastSocket中的joinGroup(SocketAddress mcastAddr,NetworkInterface netif)
今天复习了一下java网络编程这方面(其实是之前没有学好),之前在linux下用c来做过一些例子,不过不好久没有用也就忘得一干二净了.不知道c/c++的东西不太好记,还是当初没好好学. 关于组播这方面 ...
- Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面 z
http://www.cnblogs.com/zuowj/p/4504130.html 不论是B/S或是C/S结构类型,无非就是实现可供用户进行查.增.改.删,其中查询用到最多,开发设计的场景 也最为 ...
- dede如何按自己写的ID进行排序
点评:dede排序问题:如何按自己写的ID排序,更改一下函数.即可轻松实现,下面有个具体的示例,大家可以参考下. 更改一下函数,实现排序方式根据自己写的ID排序就好了. 方法: 1.打开include ...
- 97、进入ScrollView根布局页面,直接跳到页面底部,不能显示顶部内容
API使用:http://www.cnblogs.com/over140/archive/2011/01/27/1945964.html 以ScrollView为根的部局,不能从顶部显示其包含的页面内 ...
- rsync 目录 斜杠
源: 不带:同步 目录和内容 带/: 只同步内容 target目录: 待. -Warv --delete -W, --whole-file copy files whole ( ...
- Jetty提交数据时报java.lang.IllegalStateException: Form too large270468>200000问题解决
今天在使用Eclipse的Jetty插件做为服务器提交富文本编辑中的数据时,报如下异常: 在\eclipse\plugins目录下,找到org.mortbay.jetty.server_6.1.23. ...
- jQuery formValidator表单验证插件常见问题
1. 如何实现一个控件,根据不同的情况,实现不同的控制? 2. 一个页面上我有几个tab页,如何实现每个Tab页上的控件单独校验? 3. 我采用的页面上文字问题的方式,点提交的时候, ...
- 理论沉淀:隐马尔可夫模型(Hidden Markov Model, HMM)
理论沉淀:隐马尔可夫模型(Hidden Markov Model, HMM) 参考链接:http://www.zhihu.com/question/20962240 参考链接:http://blog. ...
- Java内存区域分配基恩内存溢出异常