【注】:记录自己对javascript中call与apply的见解

总会有些东西会被人拿出来重复的写来写去,为何?

只是因为自己感觉不够了解,所谓好记性不如烂笔头,并且在写的同时也会或多或少的收获到一些额外的知识,这才是重点(但是必须用心去写)

 

call 概念

概念】:调用一个对象的一个方法,以另一个对象替换当前对象 或者(劫持另外一个对象的方法,继承另外一个对象的属性)

函数】:Function.call(obj,[param1[,param2[,…[,paramN]]]])

参数】:obj:“可选项。这个对象将替代Function类里面的this。”,param1, param2,  , paramN:“可选项。将被传递方法参数序列。”

说明】:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 obj 指定的新对象。如果没有提供 obj参数,那么 Global 对象被用作 obj

例子

var a = 1, b = 2;       //申明全局变量a,b
var o = { a: 3, b: 4}    //申明对象o

//打印出当前对象
function funCall() {
    console.log(this);
}

funCall();          //直接调用-->this=window
funCall.call();     //调用funCall方法的call方法-->this=window
funCall.call(o);    //以o作为参数调用funCall方法的call方法-->this=o

 

 

apply概念

概念】:和call的意思一样,只不过是参数列表不一样

函数】:Function.apply(obj,args)

参数】:obj:“可选项。这个对象将替代Function类里面的this。”,args:“可选项。这个是数组,它将作为参数传给Function(args-->arguments)”

说明】:和call的意思一样,只不过是参数列表不一样

例子

var a = 1, b = 2;       //申明全局变量a,b
var o = { a: 3, b: 4}    //申明对象o

//打印出当前对象
function funApply() {
    console.log(this);
}

funApply();         //直接调用-->this=window
funApply.apply();   //调用funApply方法的apply方法-->this=window
funApply.apply(o);  //以o作为参数调用funApply方法的apply方法-->this=o

 

 

call与apply区别,以及什么时候用call、什么时候用apply

【this】首先说下我心中的this:哪个上下文对象调用对应的Function,Funtion中的this就是该上下文对象(Funtion中调用另外一个Funtion,this则会指向window,闭包了~~~~)

通过上述概念的介绍,可以看出call与apply的唯一区别在于参数列表(上述例子中只调用了call与apply的一个参数的重载方法)

var a = 1, b = 2, c = 5;        //申明全局变量a,b
var o = { a: 3, b: 4, e: 6}     //申明对象o

//打印出当前对象
function funCallorApply() {
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(this);
}

 

1,call的多参数调用

call多参数调用还蛮有趣的(至少我是这么理解的),它和jQuery的extend有点相似

funCallorApply.call(o, a, b, c);
//结果:
//
//
//
//Object {a: 3, b: 4, e: 6}

从上述的结果可以知道:call中的第一个参数对象会被替换成触发方法的this,后续都会被当作参数进行传递

 

2,apply的多参数调用

apply则不像call可以代入多个参数,apply只有2个参数,第二个参数需要以数组的形式存在,所以参数是以对象数组的方式进行传递。

funCallorApply.apply(o, [a, b, c]);
//结果
//
//
//
//Object {a: 3, b: 4, e: 6}

从上述结果可以知道:apply和call一样第一个参数对象会被替换被替换成触发方法的this,不通的是参数传递的方式

 

3,什么时候用call,什么时候用apply

其实我一般用的是apply,它可以将参数以对象数组的方式传递(因为我喜欢这种方式传递参数,因为这样可以在方法中设置默认值,然后通过extend继承去重新默认值)。

理论说来要看你方法是怎么构造的了

//方法是这样就可以考虑使用call
function funCallorApply(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
    //具体的实现
}
funCallorApply.call(o, a, b, c);

//方法是这样可以考虑使用apply
function funCallorApply(obj) {
    this.a = obj.a;
    this.b = obj.b;
    this.c = obj.c;
    //具体的实现
}
funCallorApply.apply(o, [a, b, c]);

一般为了方法的扩展,将参数以数组的形式进行传递是个不错的方式。如果需要改参数就不需要去动其它调用的地方了。

 

 

apply的额外补充

紫云飞的文章中发现了一点apply的额外用处(学浅,只能把第一个运用到实际开发中

 

细心的人可能已经察觉到,在我调用apply方法的时候,第一个参数是对象(this),第二个参数是一个数组集合。

在调用funCallorApply.apply(o, [a, b, c])的时候,第二参数是一个数组,但是为什么我仍然可以将数组解析为一个一个的参数?

这个就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) ,这个如果让我们用程序来实现将数组的每一个项,来装换为参数的列表,可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法:

 

1,获取数组中的最大值通过Math.max

//JavaScript中没有返回一个数组中最大值的函数.但是,有一个函数Math.max可以返回任意多个数值类型的参数中的最大值.再配合apply,我们可以实现我们的目的
Math.max.apply(null, [3, 8, 10, -1, 5]);    //结果-->10

Math.min最小值也一样应用

 

2,数组合并

//同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组
var arr1 = new Array("1", "2", "3");
var arr2 = new Array("4", "5", "6");
Array.prototype.push.apply(arr1, arr2);

Array.prototype.push.apply会返回合并后数组的length,上面结果是6,合并之后arr1就变成了["1", "2", "3", "4", "5", "6"]

 

3,4,5,6……等待发现

 

特别鸣谢

栀子花开

紫云飞[译]Apply和数组:三个技巧

Javascript call与apply记录的更多相关文章

  1. javascript call与apply关键字的作用

    apply接受两个参数.第一个参数指定函数体内this对象的指向,第二个参数为一个带下标的集合. call则是apply的语法糖,如果参数数量固定,则可以不用带下标的集合传第二个参数. 1 2 3 4 ...

  2. 《JavaScript总结》apply、call和bind方法

    在JavaScript中,apply.call.bind这个三个方法,它们的作用都是为了改变某个函数运行时的上下文, 也就是改变函数体内的this指向. 在一个函数里,存在“定义时上下文”.“运行时上 ...

  3. javascript中call,apply,bind的用法对比分析

    这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们.   关于call,apply,bind这三个函数的用法,是学习java ...

  4. 利用Image对象,建立Javascript前台错误日志记录

    手记:摘自Javascript高级程序设计(第三版),利用Image对象发送请求,确实有很多优点,有时候这也许就是一个创意点,再次做个笔记供自己和大家参考. 原文: 开发 Web 应用程序过程中的一种 ...

  5. JavaScript 之 call apply bind

    关键字 this 绑定的方法 this的动态切换,固然为JavaScript创造了巨大的灵活性,但也使得编程变得困难和模糊.有时,需要把this固定下来,避免出现意想不到的情况.JavaScript提 ...

  6. JavaScript中的apply,call与this的纠缠

    1.apply定义 apply:调用函数,并用指定对象替换函数的 this 值,同时用指定数组替换函数的参数. 语法:apply([thisObj[,argArray]]) thisObj 可选.要用 ...

  7. Javascript中的apply与call详解

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 一.方法定义 1.call 方法 语法:call([thisObj[,arg1[, arg2[, [,.arg ...

  8. JavaScript方法call,apply,caller,callee,bind的使用详解及区别

    一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). 即  “某个方法”当做“指定的某个对象”的“方法”被执行. Js代 ...

  9. JavaScript中的apply和call函数详解(转)

    每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,J ...

随机推荐

  1. poj3321

    树映射到树状数组上 非常好的题目,给了我很多启发 题目要求动态求一个棵子树的节点个数 不禁联想到了前缀和,只要我们能用一个合适的优先级表示每个顶点,那么就好做了 我们可以考虑将子树表示成区间的形式 这 ...

  2. input之placeholder与行高的问题。

    我们实现一个输入框的视觉的时候为了保持其各种各样的兼容性: 1.鼠标要跟文字一样高度. 2.文字要居中对齐. 3.还要有placeholder 第一个目标,当实现一个高度为40像素的高度输入框时,为了 ...

  3. toastr

    $(function(){     //参数设置,若用默认值可以省略以下面代     toastr.options = {         "closeButton": false ...

  4. Runnable、Callable、Future和FutureTask用法

    http://www.cnblogs.com/dolphin0520/p/3949310.html java 1.5以前创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable ...

  5. 【管理工具】Kerberos简单应用

    Kerberos这一名词来源于希腊神话“三个头的狗——地狱之门守护者”系统设计上采用客户端/服务器结构与DES加密技术,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证.可以用于防止窃听 ...

  6. [selenium webdriver Java]检查元素状态

    许多测试失败是因为点击一个元素失败或者在一个不可见的字段中输入文字,或者是在不可输入的文本中输入文字. 我们可以在具体操作之前,检查一下元素的状态.WebElement类提供了这样的方法. 方法 目的 ...

  7. httpServer V1

    package cn.edu.sss.httpServer; import java.io.BufferedReader; import java.io.IOException; import jav ...

  8. 了解常见的 Azure 灾难

    以下内容涵盖多种不同类型的灾难情况.数据中心故障不是应用程序范围内发生故障的唯一原因.设计不良或管理错误也会导致中断.请在恢复计划的设计和测试阶段设想可能导致故障的原因,这样做很重要.一个好的计划可充 ...

  9. jsp:forward与缓冲区

    jsp:forward的作用是在服务器端进行页面跳转.通常有<jsp:forward page="NewPage.jsp">语句的页面的在执行时会提前执行跳转,而不输出 ...

  10. light oj 1138 - Trailing Zeroes (III)【规律&&二分】

    1138 - Trailing Zeroes (III)   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit:  ...