JavaScript中apply与call方法
一、定义
- apply:应用某一对象的一个方法,用另一个对象替换当前对象。
- call:调用一个对象的一个方法,以另一个对象替换当前对象。
二、apply
//apply
function Person(name,age){
this.name=name;
this.age=age; this.getName=function(){
console.log("姓名:"+this.name);
} this.getAge=function(){
console.log("年龄:"+this.age);
}
} function Student(name,age,grade){
Person.apply(this,arguments);
this.grade=grade; this.getGrade=function(){
console.log("年级:"+this.grade);
}
} console.log("apply:")
var student=new Student('gkl',20,6);
student.getName();
student.getAge();
student.getGrade();
测试结果:
aaarticlea/png;base64,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" alt="" />
分析:
Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“gkl”,20,6];
student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面
三、call
call方法只是参数格式不一样
//call
function Person1(age,name){
this.name=name;
this.age=age; this.getName=function(){
console.log("姓名:"+this.name);
} this.getAge=function(){
console.log("年龄:"+this.age);
}
} function Student1(name,age,grade){
Person.call(this,age,name);
this.grade=grade; this.getGrade=function(){
console.log("年级:"+this.grade);
}
} console.log("call:");
var student1=new Student1('gkl',20,6);
student1.getName();
student1.getAge();
student1.getGrade();
效果和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来转换一下这个数组,即:
var arr1=new Array("1","2","3");
var arr2=new Array("4","5","6");
Array.prototype.push.apply(arr1,arr2);
也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合。
d) 小结:通常在什么情况下,可以使用apply类似Math.min等之类的特殊用法:
一般在目标函数只需要n个参数列表,而不接收一个数组的形式([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙地解决这个问题。
五、异同
共同之处:
- 都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。”——摘自JScript5.5 .chm
不同之处:
- apply:最多只能有两个参数——新this对象和一个数组 argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里面。如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
- call:则是直接的参数列表,主要用在js对象各方法互相调用的时候,使当前this实例指针保持一致,或在特殊情况下需要改变this指针。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
- 更简单地说,apply和call功能一样,只是传入的参数列表形式不同:如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
参考资料:
(1)http://my.oschina.net/warmcafe/blog/74973
补充资料:
(1)javascript中apply方法和call方法的作用以及prototype.js中的应用
JavaScript中apply与call方法的更多相关文章
- 关于javascript中apply()和call()方法的区别
如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语 ...
- javascript 中 apply(或call)方法的用途----对象的继承
一直以来,我的理解就是 js中的Function.apply(或者是Function.call)方法是来改变Function 这个函数的执行上下文(excute Context),说白了,就是改变执 ...
- javascript中apply()和call()方法及区别
call()和apply()方法 1.方法定义 call方法: 语法:obj.call(thisObj, arg1, arg2, ...); 定义:调用一个对象的一个方法,以另一个对象替换当前对象. ...
- javascript中apply()和call()方法的区别
一.方法的定义 call方法: 语法:call(thisObj,Object)定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来代替另一个对象调用一个方法.call ...
- (转)深入浅出 妙用Javascript中apply、call、bind
原文连接 深入浅出 妙用Javascript中apply.call.bind 网上文章虽多,大多复制粘贴,且晦涩难懂,我希望能够通过这篇文章,能够清晰的提升对apply.call.bind的认识,并且 ...
- javascript中apply、call和bind的区别,容量理解,值得转!
a) javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b) 深入浅出 妙用Javascrip ...
- 解析JavaScript中apply和call以及bind
函数调用方法 在谈论JavaScript中apply.call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: 作为函数 作为方法 作为构造函数 通过它们的call()和apply()方法间 ...
- JavaScript中this的使用方法总结
JavaScript中this的使用方法总结 在JavaScript中,this的使用分为四种场景,具体请参考阮一峰老师关于this的讲解 第一种情况是纯函数使用 var x =1 ; functio ...
- Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 ...
随机推荐
- PHP测试题讲解(20161027)
注: 关联数组 关联数组,它的每个 ID 键都关联一个值.在存储有关具体命名的值的数据时,使用数值数组不是最好的做法.通过关联数组,我们可以把值作为键,并向它们赋值. 例子 1 在本例中,我们使用一个 ...
- JavaSE之认识java
本来很早之前就应该总结自己在JavaSE中系统学到的知识了,马上就要出去工作了,想想自己还是非常菜的菜鸟,自己就夜不能寐呀.现在从zero基础开始带大家一起回顾学习的基础知识. 现在已经是凌晨了,但是 ...
- 常见Android面试题及答案(详细整理)
1. 请描述一下Activity 生命周期. 答: 如下图所示.共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onP ...
- 介绍Office 365 中文用户社区 4.0
本文于2017年3月18日首发于LinkedIn,原文链接在这里 为了给广大用户提供一个可以自由交流.切磋技术的平台,微软和其他一些国际知名的大型软件公司一样,都有创建用户社区(Community,或 ...
- iOS开发之应用沙盒
1.应用沙盒概述 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒. 应用沙盒的文件系统目录,如下图所示(假设应用的名 ...
- [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:<> [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView) 在RecyclerV ...
- 为什么使用 Containjs 模块化管理工具效率高?
为什么使用 Containjs 模块化管理工具效率高? 要说明这个首先得说明一下,Containjs 的模块加载原理. 第一步,首先使用异步加载(ajax)在 js 目录下的 app.js 入口模块( ...
- Tcl与Design Compiler (十一)——其他的时序约束选项(二)
本文如果有错,欢迎留言更正:此外,转载请标明出处 http://www.cnblogs.com/IClearner/ ,作者:IC_learner 前面介绍的设计都不算很复杂,都是使用时钟的默认行为 ...
- Python之路-计算机基础
一·计算机的组成 一套完整的计算机系统分为:计算机硬件,操作系统,软件. 硬件系统:运算器,控制器和存储器 ,输入设备,输出设备. 1.运算器:负责算数运算和逻辑运算,与控制器一起组成CPU. 2 ...
- 手机交互应用服务(状态栏提示信息Notifications)
官方的一个简单的例子: NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon ...