【注】:记录自己对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. mssql查找备注(text,ntext)类型字段为空的方法

    在sql语句中,如果查找某个文本字段值为空的,可以用select * from 表 where 字段='' ,但是如果这个字段数据类型是text或者ntext,那上面的sql语句就要出错了. 解决办法 ...

  2. linux mkfs命令参数及用法详解---linux格式化文件系统命令(包括swap分区)

    mkfs 命令  linux格式化磁盘命令           linux mkfs         指令:mkfs 使用权限 : 超级使用者 使用方式 : mkfs [-V] [-t fstype] ...

  3. Jquery拖拽原理

    /* onmousedown : 选择元素 onmousemove : 移动元素 onmouseup : 释放元素 */ 查看Demo:拖拽图片 function drag(obj) { obj.on ...

  4. [面试题] BloomFilter 无序40亿不重复 uint 整数, 给予任意的数,求是否在这40亿之中 + 无序数组中找2个相同的值

    一道百度面试题(待解中) 具体:给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中? 分析下,首先应该是空间复杂度(40亿uint ...

  5. POJ 2352 Stars

    题意:有一堆星星,每个星星的级别为坐标不高于它且不在它右边的星星个数,求级别为0-n - 1的星星个数. 解法:树状数组.输入的星星坐标已经按y坐标升序排序,y坐标相等的按x升序排序,所以每输入一个数 ...

  6. STL sort()函数

    C++之所以得到这么多人的喜欢,是因为它既具有面向对象的概念,又保持了C语言高效的特点.STL 排序算法同样需要保持高效.因此,对于不同的需求,STL提供的不同的函数,不同的函数,实现的算法又不尽相同 ...

  7. C# using SendMessage, problem with WM_COPYDATA z

    The final missing piece depends on if you are using any processor, x86 or x64. The details using the ...

  8. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问

    上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...

  9. CUDA基本概念

    CUDA计算模型 CUDA中计算分为两部分,串行部分在Host上执行,即CPU,而并行部分在Device上执行,即GPU. 相比传统的C语言,CUDA增加了一些扩展,包括了库和关键字. CUDA代码提 ...

  10. [解决]Kali Linux DHCP自动获取IP失败 坑爹的VMWare桥接

    root@kali:~# service networking restart [....] Running /etc/init.d/networking restart is deprecated ...