一、定义

  • 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方法的更多相关文章

  1. 关于javascript中apply()和call()方法的区别

    如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语 ...

  2. javascript 中 apply(或call)方法的用途----对象的继承

    一直以来,我的理解就是  js中的Function.apply(或者是Function.call)方法是来改变Function 这个函数的执行上下文(excute Context),说白了,就是改变执 ...

  3. javascript中apply()和call()方法及区别

    call()和apply()方法 1.方法定义 call方法: 语法:obj.call(thisObj, arg1, arg2, ...); 定义:调用一个对象的一个方法,以另一个对象替换当前对象. ...

  4. javascript中apply()和call()方法的区别

    一.方法的定义 call方法: 语法:call(thisObj,Object)定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来代替另一个对象调用一个方法.call ...

  5. (转)深入浅出 妙用Javascript中apply、call、bind

    原文连接 深入浅出 妙用Javascript中apply.call.bind 网上文章虽多,大多复制粘贴,且晦涩难懂,我希望能够通过这篇文章,能够清晰的提升对apply.call.bind的认识,并且 ...

  6. javascript中apply、call和bind的区别,容量理解,值得转!

    a)  javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b)  深入浅出 妙用Javascrip ...

  7. 解析JavaScript中apply和call以及bind

    函数调用方法 在谈论JavaScript中apply.call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: 作为函数 作为方法 作为构造函数 通过它们的call()和apply()方法间 ...

  8. JavaScript中this的使用方法总结

    JavaScript中this的使用方法总结 在JavaScript中,this的使用分为四种场景,具体请参考阮一峰老师关于this的讲解 第一种情况是纯函数使用 var x =1 ; functio ...

  9. Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间       ...

随机推荐

  1. jsp想js,action传值

    1.struts2 action如何向JSP的JS函数传值 action中定义变量 public class TestAction extends ActionSupport implements S ...

  2. 跑马灯、短信与反射EditText

    1.1.跑马灯功能 Android自带支持跑马灯功能,实现此功能需要设置已下属性: android:ellipsize="marquee" // 必选,跑马灯样式 android: ...

  3. 关于mui选择器的使用

    使用mui引入选择器的picker.js.poppicker.js.及他们的css文件之后引入代码与点击确定之后的状态: document.querySelector('#osex').addEven ...

  4. python多线程学习笔记(超详细)

    python threading 多线程 一. Threading简介 首先看下面的没有用Threading的程序 ):  s += i  time.sleep(  ):  s += i  time. ...

  5. C++实现四叉树

    什么是四叉树? 四叉树可以有效解决这个问题. 四叉树每一层都把地图划分四块,根据地图尺寸来决定树的层数,层数越大划分越细. 但需要对某一范围的单位筛选时,只需要定位到与范围相交的树区域,再对其区域内的 ...

  6. CognitiveJ一个Java的人脸图像识别开源分析库

    CognitiveJ 是一个开源的,支持 Java 8 API 的库,用于管理和编排 Java 应用和微软的Cognitive(Project Oxford)机器学习和图像处理库的项目,可以让你查询以 ...

  7. Tomcat之jvm及连接数设置

    一.Tomcat的JVM提示内存溢出 查看%TOMCAT_HOME%\logs文件夹下,日志文件是否有内存溢出错误 二.修改Tomcat的JVM 1.错误提示:java.lang.OutOfMemor ...

  8. javascript中replace使用总结

    ECMAScript提供了replace()方法.这个方法接收两个参数,第一个参数可以是一个RegExp对象或者一个字符串,第二个参数可以是一个字符串或者一个函数.现在我们来详细讲解可能出现的几种情况 ...

  9. dellR720重启找不到启动引导项,手动选择也无用。

    机器重启后显示 no boot device available.(如下图)检查bios中设置也是没问题的,因为装完系统后根本没动过什么.F11手动选择启动项也还是会跳到这里来. 这台机子做的Raid ...

  10. smartGWT DataSource数据动态加载

    昨天和今天早上,用DataSource从数据库后台动态加载数据,我的业务是这样的: 我有两个SelectItem选择框,第一个选择框里面的数据是单位,第二个选择框中的数据是对应单位的人,因为人可能有重 ...