一直都没太明白apply()与call()的具体使用原理,今日闲来无事,决定好好研究一番。

JavaScript中的每一个Function对象都有一个apply()方法和一个call()方法,它们的语法分别为:

/*apply()方法*/

function.apply(thisObj[, argArray])

/*call()方法*/

function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

它们各自的定义:

apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。

call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。

它们的共同之处:

都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。

它们的不同之处:

apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。

call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。

实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。

示例代码:

(1)基本用法

function add(a,b){

return a+b;

}

function sub(a,b){

return a-b;

}

var a1 = add.apply(sub,[4,2]);  //sub调用add的方法

var a2 = sub.apply(add,[4,2]);

alert(a1); //6

alert(a2); //2

/*call的用法*/

var a1 = add.call(sub,4,2);

(2)实现继承

function Animal(name){

this.name = name;

this.showName = function(){

alert(this.name);

}

}

function Cat(name){

Animal.apply(this,[name]);

}

var cat = new Cat("咕咕");

cat.showName();

/*call的用法*/

Animal.call(this,name);

(3)多重继承

function Class10(){

this.showSub = function(a,b){

alert(a - b);

}

}

function Class11(){

this.showAdd = function(a,b){

alert(a + b);

}

}

function Class12(){

Class10.apply(this);

Class11.apply(this);

// Class10.call(this);

//Class11.call(this);

}

var c2 = new Class12();

c2.showSub(3,1); //2

c2.showAdd(3,1); //4

apply的一些其他巧妙用法

(1)Math.max 可以实现得到数组中最大的一项:

因为Math.max不支持Math.max([param1,param2])也就是数组,但是它支持Math.max(param1,param2...),所以可以根据apply的特点来解决 var max=Math.max.apply(null,array),这样就轻易的可以得到一个数组中的最大项(apply会将一个数组转换为一个参数接一个参

数的方式传递给方法)

这块在调用的时候第一个参数给了null,这是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,所以直接传递了一个null过去。

用这种方法也可以实现得到数组中的最小项:Math.min.apply(null,array)

(2)Array.prototype.push可以实现两个数组的合并

同样push方法没有提供push一个数组,但是它提供了push(param1,param2...paramN),同样也可以用apply来转换一下这个数组,即:

var arr1=new Array("1","2","3");

var arr2=new Array("4","5","6");

Array.prototype.push.apply(arr1,arr2); //得到合并后数组的长度,因为push就是返回一个数组的长度

也可以这样理解,arr1调用了push方法,参数是通过apply将数组转换为参数列表的集合

通常在什么情况下,可以使用apply类似Math.max等之类的特殊用法:

一般在目标函数只需要n个参数列表,而不接收一个数组的形式,可以通过apply的方式巧妙地解决这个问题。

java apply_apply()与call()的区别相关推荐

  1. JAVA 中equals()与==的区别

    原文地址:http://www.chineselinuxuniversity.net/articles/29594.shtml 值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存 ...

  2. Java NIO与IO的区别和比较

    Java NIO与IO的区别和比较 导读 J2SE1.4以上版本中发布了全新的I/O类库.本文将通过一些实例来简单介绍NIO库提供的一些新特性:非阻塞I/O,字符转换,缓冲以及通道. 一. 介绍NIO ...

  3. java中Array和ArrayList区别 可以将 ArrayList想象成一种会自动扩增容量的Array

    java中Array和ArrayList区别 1)精辟阐述: 可以将 ArrayList想象成一种"会自动扩增容量的Array https://blog.csdn.net/ywjy10280 ...

  4. JAVA CLASSPATH 和PATH的区别 经典

    JAVA CLASSPATH 和PATH的区别 收藏 PATH: 用来指定 java 虚拟机(JVM) 所在在目录,也就是我们最常用的用来编译java源程序的javac.exe 和用来执行 *.cla ...

  5. java 接口与抽象类的区别

    1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法 ...

  6. 面试必问一:Java 中 == 和 equals 的区别你知道吗

    面试必问一:Java 中 == 和 equals 的区别你知道吗 前言 关于这个问题,一般初中级面试中都会遇到,还记得我当初实习找工作的时候也遇到了这个问题,现在都还记得自己是怎么回答的:== 是基本 ...

  7. POPTEST老李谈JVM、JRE、JDK、java ee sdk with jdk区别

    POPTEST老李谈JVM.JRE.JDK.java ee sdk with jdk区别 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作 ...

  8. 一文告诉你 Java RMI 和 RPC 的区别

    转载自  一文告诉你 Java RMI 和 RPC 的区别 RPC 远程过程调用 RPC(Remote Procedure Call Protocol)远程过程调用协议,通过网络从远程计算机上请求调用 ...

  9. Java之Socket与HTTP区别

    转自: Java之Socket与HTTP区别 - 曹刚 - 博客园我们都知道TCP/IP协议共分四层:①链路层,有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接 ...

最新文章

  1. 在温暖的南方惠州①月了。。
  2. 点云数据格式 数据集笔记
  3. IDEA快捷键(修改成eclipse版)+Templates
  4. 行政区村界线_工作动态 | 龟山镇召开村级行政区域界线勘定工作暨民政业务培训会议...
  5. mysql Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nona
  6. 2014/School_C_C++_B/3/x的x次幂
  7. gitee提交代码_git 版本控制,github和gitee
  8. 【docker】第二节:安装nginx、mysql、php
  9. 面向对象——意图与逻辑(五)
  10. 操作系统—内存的基础知识
  11. linux系统 锐捷_Ubuntu Linux锐捷安装方法
  12. 一文将 DCDC 的 Layout 讲的明明白白,收藏这篇就够了
  13. arcgis剔除异常值栅格计算器_arcgis 栅格计算器(Spatial Analyst/Raster Calculator)
  14. CTEX加中英文摘要
  15. 剑指Offer--045-孩子们的游戏(圆圈中最后剩下的数)--约瑟夫环
  16. android 5.1一键root工具箱,s大师一键root下载
  17. Human Pose Estimation姿态估计调研
  18. 联想计算机搜不到mfp,电脑检测不到联想LJ2200L打印机
  19. 新版天猫刷红包js代码以及使用方式增加砸金砖代码
  20. SMS格式编码与解码

热门文章

  1. Android通讯录管理(获取联系人、通话记录、短信消息)(三)
  2. 股权激励的作用是什么
  3. 【visdom绘图】深度学习中Visdom绘图的总结
  4. 荣耀系列可以用鸿蒙系统吗,即将发布的荣耀50系列手机可以有机会用鸿蒙系统吗?...
  5. Noteshelf - 新的注释应用为iOS
  6. Vue cmd窗口创建项目(初学版本)
  7. 小红书未能找到主机名的服务器,小红书未能找到使用主机名的服务器是怎么回事-小红书未能找到使用主机名的服务器是什么意思...
  8. python控制启动防病毒软件的作用是_122、防病毒软件的作用是_______。 A) 检查计算机是否染有病毒,消除已感染的任何病毒 B) 杜绝病毒对计算...
  9. 解决阿里云服务器redis连接超时
  10. vs2019 安装完成没有反应_vs2019安装失败解决方法