- 浏览: 194552 次
- 性别:
- 来自: QD
文章分类
- 全部博客 (127)
- Struts2 (8)
- Web (27)
- 计算机基础 (2)
- 面试 (2)
- JQuery (4)
- MySQL (1)
- SQL (1)
- AJAX (3)
- Java (17)
- Javascript (36)
- 情感 (0)
- Oracle (7)
- Spring (5)
- FreeMarker (2)
- JSON (1)
- 表达式 (1)
- 线程 (4)
- WebService (10)
- MyEclipse (2)
- LDAP (1)
- Tomcat (1)
- NIO (1)
- Linux (1)
- ExtJS (4)
- Android (1)
- Dojo (2)
- Maven (9)
- Ant (7)
- 分布式 (1)
- Intellij IDEA (1)
最新评论
-
northc:
米饭军 写道如果文件已存在怎样避免应该会覆盖的
用Ant scp往远程linux传文件 -
米饭军:
如果文件已存在怎样避免
用Ant scp往远程linux传文件 -
luis025:
不支持列隐藏 硬伤
ExtJS4.0 分享Grid导出Excel插件(3.28更新支持4.1) -
rgbhje:
楼主大神,我把你的代码简单改了一小下,在4.2可以跑了
ExtJS4.0 分享Grid导出Excel插件(3.28更新支持4.1) -
rgbhje:
楼主大神,我把你的代码简单改了一小下,在4.2可以跑了
ExtJS4.0 分享Grid导出Excel插件(3.28更新支持4.1)
from:http://www.popo4j.com/article/the-differences-of-apply-and-call.html
如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语言过程中遇到这种感觉,那么就从现在形始,请放下的您的”偏见”,因为这对您来说绝对是一片新大陆,让JavaScrip慢慢融化以前一套凝固的编程意识,注入新的生机!
好,言归正传,先理解JavaScrtipt动态变换运行时上下文特性,这种特性主要就体现在apply, call两个方法的运用上.
区分apply,call就一句话,
1 |
foo.call( this , arg1,arg2,arg3) == foo.apply( this , arguments)== this .foo(arg1, arg2, arg3)
|
call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性.既然作为方法的属性,那它们的使用就当然是针对方法的了.这两个方法是容易混淆的,因为它们的作用一样,只是使用方式不同.
相同点:两个方法产生的作用是完全一样的
不同点:方法传递的参数不同
那什么是方法产生的作用,方法传递的参数是什么呢?
我们就上面的foo.call(this, arg1, arg2, arg3)展开分析.
foo是一个方法,this是方法执行时上下文相关对象,arg1, arg2, arg3是传给foo方法的参数.这里所谓的方法执行时上下文相关对象, 如果有面向对象的编程基础,那很好理解,就是在类实例化后对象中的this.
在JavaScript中,代码总是有一个上下文对象,代码处理该对象之内. 上下文对象是通过this变量来体现的, 这个this变量永远指向当前代码所处的对象中.
为了更好的领会这this是什么,举个例子.
01 |
/创建一个A类 |
02 |
function A(){
|
03 |
//类实例化时将运行以下代码 |
04 |
//此时的执行上下文对象就是this,就是当前实例对象 |
05 |
this .message = “message of a”;
|
06 |
this .getMessage = function (){
|
07 |
return this .message;
|
08 |
} |
09 |
} |
10 |
//创建一个A类实例对象 |
11 |
var a = new A();
|
12 |
//调用类实例getMessage方法获得message值 |
13 |
alert(a.getMessage()); |
14 |
//创建一个B类 |
15 |
function B(){
|
16 |
this .message = ”message of b”;
|
17 |
this .setMessage = function (msg){
|
18 |
this .message = msg;
|
19 |
} |
20 |
} |
21 |
//创建一个B类实例对象 |
22 |
var a = new B();
|
题外话:javascript对象所有属性都是公开的(public),没私有(private)之说,所以也可直接访问message属性
alert(a.message);
可见,A, B类都有一个message属性(面向对象中所说的成员),A有获取消息的getMessage方法,B有设置消息的setMessage方法,下面来显示call的威力.
1 |
//给对象a动态指派b的setMessage方法,注意,a本身是没有这方法的! |
2 |
b.setMessage.call(a, “a的消息”); |
3 |
//下面将显示”a的消息” |
4 |
alert(a.getMessage()); |
5 |
//给对象b动态指派a的getMessage方法,注意,b本身也是没有这方法的! |
这就是动态语言 JavaScript call的威力所在!
简直是”无中生有”,对象的方法可以任意指派,而对象本身一直都是没有这方法的,注意是指派,通俗点就是,方法是借给另一个对象的调用去完成任务,原理上是方法执行时上下文对象改变了.
所以 b.setMessage.call(a, “a的消息”); 就等于用a作执行时上下文对象调用b对象的setMessage方法,而这过程中与b一点关系都没有, 作用等效于a.setMessage( “a的消息”);
因为apply与call产生的作用是一样的,可以说
call, apply作用就是借用别人的方法来调用,就像调用自己的一样.
好,理解了call, apply相同处—–作用后,再来看看它们的区别,看过上面例子,相信您大概知道了.
从 b.setMessage.call(a, “a的消息”) 等效于 a.setMessage( “a的消息”) 可以看出, “a的消息”在call中作为一个参数传递,
那么在apply中是怎么表示的呢,直接解释说不清楚,apply要结合应用场景才一目了然.我们来设计一个应用场景:
01 |
function print(a, b, c, d){
|
02 |
alert(a + b + c + d); |
03 |
} |
04 |
function example(a, b , c , d){
|
05 |
//用call方式借用print,参数显式打散传递 |
06 |
print.call( this , a, b, c, d);
|
07 |
//用apply方式借用print, 参数作为一个数组传递, |
08 |
//这里直接用JavaScript方法内本身有的arguments数组 |
09 |
print.apply( this , arguments);
|
10 |
//或者封装成数组 |
11 |
print.apply( this , [a, b, c, d]);
|
12 |
} |
13 |
//下面将显示”背光脚本” |
14 |
example(”背” , “光” , “脚”, “本”); |
在这场景中, example方法内,a, b, c, d作为方法传递的参数, 方法分别运用了apply, call去借print方法来调用,
最后一句由于直接调用example方法, 所以在该方法中的上下文对象this就是window对象.
所以,call, apply方法它们除了第一个参数,即执行时上下文对象相同外,call方法的其它参数将依次传递给借用的方法作参数,而apply就两个参数,第二个参数为一个数组传递.所以可以说成
call, apply方法区别是,从第二个参数起, call方法参数将依次传递给借用的方法作参数, 而apply直接将这些参数放到一个数组中再传递, 最后借用方法的参数列表是一样的.
应用场景:
当参数明确时可用call, 当参数不明确时可用apply给合arguments
1 |
//例 |
2 |
print.call(window, “背” , “光” , “脚”, “本”); |
3 |
//foo参数可能为多个 |
4 |
function foo(){
|
5 |
print.apply(window, arguments); |
6 |
} |
01 |
var oP = Object.prototype,
|
02 |
toString = oP.toString; |
03 |
04 |
console.log(toString.call([123])); //[object Array]
|
05 |
console.log(toString.call( '123' )); //[object String]
|
06 |
console.log(toString.call({a: '123' })); //[object Object]
|
07 |
console.log(toString.call(/123/)); //[object RegExp]
|
08 |
console.log(toString.call(123)); //[object Number]
|
09 |
console.log(toString.call(undefined)); //[object Undefined]
|
10 |
console.log(toString.call( null )); //[object Null]
|
11 |
//.... |
标准浏览器中完美的作到,但是(为什么要说但是呢)IE6中,却会出现以下问题:
01 |
var oP = Object.prototype,
|
02 |
toString = oP.toString; |
03 |
04 |
function typeOf(value) {
|
05 |
if ( null === value) {
|
06 |
return 'null' ;
|
07 |
}
|
08 |
09 |
var type = typeof value;
|
10 |
if ( 'undefined' === type || 'string' === type) {
|
11 |
return type;
|
12 |
}
|
13 |
14 |
var typeString = toString.call(value);
|
15 |
switch (typeString) {
|
16 |
case '[object Array]' :
|
17 |
return 'array' ;
|
18 |
case '[object Date]' :
|
19 |
return 'date' ;
|
20 |
case '[object Boolean]' :
|
21 |
return 'boolean' ;
|
22 |
case '[object Number]' :
|
23 |
return 'number' ;
|
24 |
case '[object Function]' :
|
25 |
return 'function' ;
|
26 |
case '[object RegExp]' :
|
27 |
return 'regexp' ;
|
28 |
case '[object Object]' :
|
29 |
if (undefined !== value.nodeType) {
|
30 |
if (3 == value.nodeType) {
|
31 |
return (/\S/).test(value.nodeValue) ? 'textnode' : 'whitespace' ;
|
32 |
} else {
|
33 |
return 'element' ;
|
34 |
}
|
35 |
} else {
|
36 |
return 'object' ;
|
37 |
}
|
38 |
default :
|
39 |
return 'unknow' ;
|
40 |
}
|
41 |
} |
发表评论
-
Ext Toolbar换行
2012-06-21 09:02 01.var oneTbar=new Ext.Toolba ... -
禁止select控件選擇
2012-06-20 20:06 0禁止select控件選擇 大家知道, 對於HTML控件 ... -
几种压缩算法原理介绍
2012-05-25 20:04 1369先给出一个JS实现的ZIP:http://stuartk ... -
ExtJS4.0 分享Grid导出Excel插件(3.28更新支持4.1)
2012-03-12 17:00 10908需要将ExtJS Grid 导出 Excel 的同学可以试一试 ... -
Ext Js 4.x 扩展自己的XType
2012-03-03 14:26 1565如果想用自己定制的XType(比如这里想用一个Obj存 ... -
(转)Javascript中大括号“{}”的多义性
2012-02-25 11:21 1015JS中大括号有四种语义作用语义1,组织复合语句,这是最常 ... -
function sleep
2012-02-17 19:16 890//毫秒 (function sleep(t){ ... -
不用递归,循环算0-9999之和(js)
2012-02-17 19:15 898var i=0,sum=eval(new Arra ... -
Augment.js 为旧浏览器增加现代Javascript的功能支持
2012-01-18 12:06 1085index: http://olivernn. ... -
Javascript中的~和~~
2011-12-30 15:58 886<script type="text/j ... -
js中的onchange和onpropertychange
2011-12-28 11:26 1851当一个HTML元素的属 ... -
parentNode、parentElement,childNodes、children
2011-12-26 17:38 936parentNode、parentElement,childN ... -
关于JS中的constructor与prototype
2011-12-22 19:53 1015我们都知道,在JS中有一个function的东西。一般人 ... -
各浏览器对document.getElementById等方法的实现差异
2011-12-21 13:15 935本文来自:http://www.cnblogs.com/sna ... -
全世界最短的IE判定
2011-12-20 15:45 808var ie = !-[1,]; ... -
document.getElementsByClassName的理想实现
2011-12-20 14:41 1446来自: 司徒正美 blog http://www.cnblo ... -
浏览器支持的JS版本及JS对象图
2011-12-20 10:38 1091来自zh.wikipedia.org的JavaScript ... -
JS判断浏览器能力
2011-12-15 20:47 1059对象/特征检测法 该方法是一种判断浏览器能力(而非浏览器 ... -
onunload和onbeforeunload区别
2011-12-15 18:54 981Onunload,onbeforeunload都是在刷 ... -
收藏的两个多tab切换
2011-12-13 19:02 957留着可能以后有用
相关推荐
在JavaScript中,`apply()` 和 `call()` 是两种非常重要的函数调用方式,它们都允许开发者改变函数调用时的上下文(即`this`的指向)并传递参数。这两种方法对于理解和掌握JavaScript的动态性至关重要,特别是对于从...
然而,数据字典往往缺乏记录字段间逻辑关系和表概念定义的细节,因此,我们还需要借助其他工具或实际操作来进行深入分析。 ### 第二步:分门别类 数据探索的第二步是根据主题缩小研究范围,并将相关的字段进行分组...
计算机前端-实战.目视频2-06.理清rbac表之间的关系.wmv
在画用例图的时候,理清用例之间的关系是重点。用例的关系有泛化(generalization)、扩展(extend)和包含(include)。...泛化(generalization):泛化关系是一种继承关系,子用例将继承基用例的所有行为,关系和通信关系
### 理清概念:数据、信息、知识和智慧之间的关系 #### 一、引言 在当今数字化时代,我们每天都被大量的数据所包围。这些数据不仅仅是简单的数字或符号,而是构成了我们的工作环境、日常生活乃至整个社会的基础。...
固定资产管理方法:制作台账和盘点库房、年度盘点和全面理清资产方法.pdf
亲属是基于婚姻、血缘和法律拟制而形成的社会关系。亲属关系包括夫妻、父母、子女、兄弟姊妹、祖父母和外祖父...让您准确的叫出亲戚称谓,理清亲属之间的亲戚关系,轻松掌握中国式的亲戚关系换算,让你更了解中国文化。
gcc,libc,glibc的关系
【大阅读理清文章思路学习教案】主要针对的是如何理解和分析文章的结构、内容与主旨,这在学术和教育领域尤为重要,尤其是对于处理文学作品和科学论著等不同类型的文本。文章思路的理解不仅关乎到对文章层次结构的...
一文理清国有企业董事会、经理层决策重大问题的前置程序时的权责边界.pdf
理清框架与脉络是指在需求分析阶段建立一个明确、结构化的思路,以便于后续的设计、编码和测试。这篇博文“需求分析 理清框架与脉络”可能详细阐述了如何进行有效的需求分析,以及如何构建项目的整体框架。 首先,...
- **详细概述围绕线索展开的人物、时间、地点和事件的起因、经过和结果,以及情感表达。** **四、判断线索的技巧** 1. **线索特点**:贯穿全文且反复出现,将材料紧密联系。 2. **找线索的方法** - **了解文章...
理清Hadoop1.x与Hadoop2.x区别,对比分析。 Hadoop是大数据惊世之作,必学的东西,需要知道: 它由哪些部分组成? 各自的作用是什么? 如果工作的?
4. 答题策略:理解和分析论证结构时,需要关注段落间的逻辑关系,理解关键词句,识别过渡段或句,理清论点和论据之间的关系,以及论证方法的运用。 5. 论证过程分析:第③段首先提出孩童时期是培养读书习惯和能力的...
- 部管理关系、行政隶属关系、业务指导关系、垂直管理关系和属地管理关系是政务关系的具体体现。 5. 公文写作的过程: - 包括公文准备阶段、起草阶段、修改阶段和整理阶段。 - 准备阶段需要收集信息、明确依据、...
梳理Informatic的元数据,理清ETL背后的数据加工流水线基础数据,基于SQL析可以获取目标表依赖的源表和映射,然后基于映射可以追溯到相应的会话、工作集、工作流,完成整个数据加工链的血缘
2. **分支与子分支**:软件允许用户添加多个分支,每个分支可以进一步细分,以展示层次结构和逻辑关系。 3. **图形元素**:Sharemind可能提供各种图形和符号,使导图更具视觉吸引力,更便于理解。 4. **颜色编码**...
源代码转流程图工具是一种非常实用的软件开发辅助工具,它能够将编程语言的源代码自动解析并生成相应的流程图,帮助程序员更好地理解和分析代码结构。这种工具支持多种编程语言,包括C、C++、VC++(Visual C++)、...