【JavaScript】apply和call的区别在哪?

我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家分享.. 如有什么不对的或者说法不明确的地方希望读者多多提一些意见,以便共同提高.. 主要我是要解决一下几个问题:

1. apply和call的区别在哪里 
2. 什么情况下用apply,什么情况下用call 
3. apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定义,然后用示例来解释这两个方法的意思和如何去用.
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性. 
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象 
args:这个是数组,它将作为参数传给Function(args-->arguments)
call:和apply的意思一样,只不过是参数列表不一样.
Function.call(obj,[param1[,param2[,…[,paramN]]]]) 
obj:这个对象将代替Function类里this对象 
params:这个是一个参数列表
1.        apply示例:

 

  1. <script type="text/javascript">  
  2.     /*定义一个人类*/  
  3.     function Person(name,age)  
  4.     {  
  5.         this.name=name;  
  6.         this.age=age;  
  7.     }  
  8.     /*定义一个学生类*/  
  9.     functionStudent(name,age,grade)  
  10.     {  
  11.         Person.apply(this,arguments);  
  12.         this.grade=grade;  
  13.     }  
  14.     //创建一个学生类   
  15.     var student=new Student("qian",21,"一年级");  
  16.     //测试   
  17.     alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);  
  18.     //大家可以看到测试结果name:qian  age:21  grade:一年级   
  19.     //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.   
  20. </script>  
 

 

 

  1. <script type="text/javascript">  
  2.     /*定义一个人类*/  
  3.     function Person(name,age)  
  4.     {  
  5.         this.name=name;  
  6.         this.age=age;  
  7.     }  
  8.     /*定义一个学生类*/  
  9.     functionStudent(name,age,grade)  
  10.     {  
  11.         Person.apply(this,arguments);  
  12.         this.grade=grade;  
  13.     }  
  14.     //创建一个学生类  
  15.     var student=new Student("qian",21,"一年级");  
  16.     //测试  
  17.     alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);  
  18.     //大家可以看到测试结果name:qian  age:21  grade:一年级  
  19.     //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.  
  20. </script>  
 

 

分析: Person.apply(this,arguments);

this:在创建对象在这个时候代表的是student

arguments:是一个数组,也就是[“qian”,”21”,”一年级”];

                   也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面

 

 

2.        call示例

在Studen函数里面可以将apply中修改成如下:

Person.call(this,name,age);

这样就ok了

3.        什么情况下用apply,什么情况下用call

在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));

4.        apply的一些其他巧妙用法

细心的人可能已经察觉到,在我调用apply方法的时候,第一个参数是对象(this), 第二个参数是一个数组集合, 在调用Person的时候,他需要的不是一个数组,但是为什么他给我一个数组我仍然可以将数组解析为一个一个的参数,这个就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) 这个如果让我们用程序来实现将数组的每一个项,来装换为参数的列表,可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法:

 

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

因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组

但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项(apply会将一个数组装换为一个参数接一个参数的传递给方法)

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

b)        Math.min  可以实现得到数组中最小的一项

同样和 max是一个思想 var min=Math.min.apply(null,array);

c)        Array.prototype.push 可以实现两个数组合并

同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即:

 

  1. vararr1=new Array("1","2","3");  
  2.   
  3. vararr2=new Array("4","5","6");  
  4.   
  5. Array.prototype.push.apply(arr1,arr2);  
 

 

 

  1. vararr1=new Array("1","2","3");  
  2.   
  3. vararr2=new Array("4","5","6");  
  4.   
  5. Array.prototype.push.apply(arr1,arr2);  
 

 

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

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

一般在目标函数只需要n个参数列表,而不接收一个数组的形式([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙地解决这个问题!

5.        总结:

一开始我对apply 非常的不懂,最后多看了几遍,自己多敲了几遍代码,才明白了中间的道理,所以,不管做什么事情,只要自己肯动脑子,肯动手敲代码,这样一个技术就会掌握…   

还有比如第四部分得内容,巧妙的解决了实实在在存在的问题,这个肯定不是一个初学者能想到的解决方案(这个也不是我自己想的),没有对编程有一定认识的不会想到这个的,还是一句话,多积累,多学习,提升自己的能力和对编程思想的理解能力才是最关键!

 

http://xuqian0808.blog.163.com/blog/static/17012571020137275316855/

转载于:https://www.cnblogs.com/daishuguang/p/3933894.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php js动态显示系统时间,PHP+JS动态显示服务器时间

摘要&#xff1a;JS默认只能获取当前系统时间&#xff0c;若想获取服务器时间&#xff0c;必须加上后端语言配合&#xff0c;PHPJS获取服务器端时间代码&#xff1a;运行结果&#xff1a;2017-4-4 15:...JS默认只能获取当前系统时间&#xff0c;若想获取服务器时间&#xff0c;…

SQL中的事物【转】

来源于&#xff1a;http://www.cnblogs.com/zhuifengnianshao/archive/2010/11/24/1886939.html事务&#xff08;Transaction&#xff09;是并发控制的单位&#xff0c;是用户定义的一个操作序列。这些操作要么都做&#xff0c;要么都不做&#xff0c;是一个不可分割的工作单位…

Mybaitis JdbcType 和javaType

2019独角兽企业重金招聘Python工程师标准>>> MyBatis 通过包含的jdbcType类型 BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINEDTINYINT REAL VARCHAR BINARY BLOB NVARCHARSMALLINT DOUBLE …

装箱和拆箱(js的问题)

装箱&#xff1a;基本数据类型 -> 引用数据类型 var num 123; var numObj new Number(123);console.log(typeof num) // number console.log(typeof numObj) // object 拆箱&#xff1a;引用数据类型 -> 基本数据类型 var numObj new Number(123);console.log(numO…

php文件缓存代码,php文件缓存实例代码

php教程文件缓存实例代码缓存在实际使用当中应用很广泛&#xff0c;可以减轻对服务器数据库教程的访问&#xff0c;提高运行速度。目前很多cms内容管理系统中频繁使用缓存机制来提高系统运行的效率cache.php 代码如下&#xff1a;php代码/*用户需要事先定义的常量&#xff1a;_…

[架构] 分布式和集群的区别

一次在群里面看到群友们在讨论这个的区别&#xff0c;看了他们发表的言论&#xff0c;觉得很有道理&#xff0c;很通俗易懂&#xff0c;就当做学习的笔记记录在这里&#xff1a; 用两个例子看清楚分布式和集群的区别&#xff1a; 例子1&#xff1a; 如果一个任务由10个子任务组…

JQuery.lazyload 图片延迟加载

1.引入 jquery.lazyload.js 2. 延时加载的方式 <script type"text/javascript">   $(function() {     $("img").lazyload({     effect : "fadeIn"    });   });   </script> 3. 把阀值设置成200 意思就是当图…

如何把UIView转成UIImage,解决模糊失真问题

最近工作中&#xff0c;遇到一个需求&#xff0c;需要把一个UIView对象转成UIImage对象显示。经过网络搜索&#xff0c;找到如下答案&#xff1a; ?12345678-(UIImage*)convertViewToImage:(UIView*)v{CGSize s v.bounds.size;UIGraphicsBeginImageContext(s);[v.layer rende…

php数据趋势曲线,数据曲线图怎么做

数据曲线图怎么做&#xff1f;1、在电脑桌面上&#xff0c;新建一个excel文件(操作过程即为点击右键&#xff0c;在选项中选择“新建”选项&#xff0c;然后再选择“excel文件”&#xff0c;即可成功新建excel文件了)2、双击将新建的excel文件打开&#xff0c;输入你需要统计制…

ceph 分布式存储安装

[rootlocalhost ~]# rm -rf /etc/yum.repos.d/*.repo 下载阿里云的base源 [rootlocalhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo [rootlocalhost ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/r…

基本技能

1、分析Android游戏积分机制、付费机制、存档机制2、游戏破解嵌入特定页面&#xff0c;页面涵盖logo&#xff0c;url外链等基础内容3、破解游戏呈现无限金币、免费道具、无敌等表现方式1、精通汇编语言、Java或C/C语言&#xff0c;对逆向工程有浓厚兴趣2、有代表作品3、 熟练掌…

STM32学习之路-SysTick的应用(时间延迟)

开发板&#xff1a;奋斗V5 好~ 菜B要来搞实验了.. 前面已经说了SysTick的工作原理什么的了,这里就不说了.. 先来做第一个实验&#xff1a; 盗自奋斗的样例,嘿嘿, 用SysTick产生1ms的基准时间,产生中断,每秒闪烁一次(LED1 V6) &#xff08;1&#xff09;外围时钟初始化&#xf…

centos akonadi mysql,MySQL数据库之在CentOS7上安装MySQL5.7

本文主要向大家介绍了MySQL数据库之在CentOS7上安装MySQL5.7 &#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习MySQL数据库有所帮助。获取RPM包# wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm列出RPM包里都有哪些文件# rpm -q…

usaco-crypt1-pass

这个想了半天&#xff0c;终于过了&#xff1a; /* ID: qq104801 LANG: C TASK: crypt1 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h>void debug_dummy() {return; }int n; int d[10];int numlen(int x) { …

凡事预则立(Beta)

听说——凡事预则立 吸取之前alpha冲刺的经验教训&#xff0c;也为了这次的beta冲刺可以更好更顺利地进行&#xff0c;更是为了迎接我们的新成员玮诗。我们开了一次组内会议&#xff0c;进行beta冲刺的规划。 上一张我们的合照&#xff1a; 具体会议议程如下&#xff1a; 1、讨…

tomcat 指定的服务未安装(总结验证)

如果你的tomcat是解压版的&#xff0c;解压版的话要环境配置一、jdk环境变量一定要配置对&#xff0c;如果配置不对也会出现此提示 1&#xff0c;新建变量名&#xff1a;JAVA_HOME&#xff0c;变量值&#xff1a;C:\Program Files\Java\jdk1.7.02&#xff0c;打开PATH&#xff…

java url 授权,Spring MVC框架 - 基本认证之URL 授权认证

[导读]为控制器添加注解是非常简单的&#xff0c;但这往往并不是最可行的方案。有时候&#xff0c;我们会想要完全控制授权功能。为控制器添加注解是非常简单的,但这往往并不是最可行的方案。有时候,我们会想要完全控制授权功能。移除Secured 注解,我们将会采用一种更好的方案。…

什么原因成就了一位优秀的程序员?(转)

这些年我曾和很多程序员一起工作&#xff0c;他们之中的一些人非常厉害&#xff0c;而另一些人显得平庸。不久前因为和一些技术非常熟练的程序员工作感觉很愉快&#xff0c;我花了一些时间在考虑我佩服他们什么呢&#xff1f;什么原因让优秀的程序员那么优秀&#xff0c;糟糕的…

用Vue.js开发一个电影App的前端界面

我们要构建一个什么样的App&#xff1f; 我们大多数人使用在线流媒体服务&#xff08;如Netflix&#xff09;观看我们最喜欢的电影或者节目。这篇文章将重点介绍如何通过使用vue.js 2 建立一个类似风格的电影流媒体WEB交互界面&#xff08;见上图&#xff09;。 最终的产品可以…

eclipse 函数折叠展开

为什么80%的码农都做不了架构师&#xff1f;>>> 一、eclipse 代码块折叠显示 核查是否开启折叠功能全局folding(window->preference->Gerneral->Editor-Structured Text)右侧Appearance 勾选Enable folding检测对应源编辑&#xff08;java/javaScript&…