apply()和call()的方法的区别

参考文档https://www.cnblogs.com/lengyuehuahun/p/5643625.html

一直都没太明白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); // /*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的方式巧妙地解决这个问题。

apply()和call()的方法的更多相关文章

  1. JavaScript的apply()方法和call()方法

    1 <script type="text/javascript"> 2 /*定义一个人类*/ 3 function Person(name,age) 4 { 5 thi ...

  2. 利用apply和arguments复用方法

    首先,有个单例对象,它上面挂了很多静态工具方法.其中有一个是each,用来遍历数组或对象. var nativeForEach = [].forEach var nativeMap = [].map ...

  3. JavaScript中的apply()方法和call()方法使用介绍

    1.每个函数都包含两个非继承而来的方法:apply()和call(). 2.他们的用途相同,都是在特定的作用域中调用函数. 3.接收参数方面不同,apply()接收两个参数,一个是函数运行的作用域(t ...

  4. 彻底理解了call()方法,apply()方法和bind()方法

    javascript中的每一个作用域中都有一个this对象,它代表的是调用函数的对象.在全局作用域中,this代表的是全局对象(在web浏览器中指的是window).如果包含this的函数是一个对象的 ...

  5. apply方法和call方法。函数属性与方法。

    每个函数都有length属性哥prototype属性. length属性表示的是函数接入参数的个数 在es引用类型语言中,prototype是保存它们所有实例方法的真正所在.换句话来说,类似于toSt ...

  6. AngularJs $scope 里面的$apply 方法和$watch方法

    Angular $scope 里面的$apply 方法 Scope提供$apply方法传播Model变化 <!DOCTYPE html> <html> <head> ...

  7. 【JavaScript】call和apply区别及使用方法

    一.方法的定义call方法: 语法:fun.call(thisArg[, arg1[, arg2[, ...]]])定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来 ...

  8. apply方法和call方法的详解2

    1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定 ...

  9. apply()方法和call()方法

    obj.func.call(obj1)       //是将obj1看做obj,调用func方法,将第一个参数看做函数调用的对象,可以看做,将obj的方法给obj1使用 ECMAScript规范给所有 ...

随机推荐

  1. 埃利斯(A.Ellis)ABCDE情绪管理理论

    埃利斯(A.Ellis)ABCDE情绪管理理论A :Activating Events(诱发事件)B :Beliefs(个体对诱发事件的评价.解释.看法)C :Consequences(个体情绪和行为 ...

  2. SmartTest__自动随机填充表单数据

    下载地址https://addons.mozilla.org/zh-CN/firefox/addon/smarttesttool/ 安装完成后可以在工具栏看见 目前只包含两个功能 测试使用

  3. Callable和Supplier的区别

    A Callable is "A task that returns a result, while a Supplier is "a supplier of results&qu ...

  4. 分布式存储ceph--添加/删除osd(5)

    一.添加osd: 当前ceph集群中有如下osd,现在准备新添加osd:

  5. Linux 查看CPU和内存的使用情况

    Linux 查看CPU和内存的使用情况 如何查看Linux机器的CPU和内存的使用情况. 可以通过如下方式: 1.查看CPU和内存的实时使用情况 使用如下命令: top 命令执行后,效果如下(资源的使 ...

  6. Linux系统管理_主题01 :初识Linux_1.6 用好帮助文档man

    在 man 界面中,可以使用如下快捷键来进行操作:  上/下箭头 向上/下滚动一行  [Space] 向下翻一页  [Page Down] 向下翻一页  [Page Up] 向上翻一页  [ ...

  7. uni-app 实现热更新

    前端打包 app 即把写好的静态资源文件套壳打包成 app ,而热更新即下载并替换 app 内部的静态资源文件,实现 app 的版本升级. 在uni-app 中,我们是如何实现热更新的呢?下面来看代码 ...

  8. ASP.NET Core 入门笔记10,ASP.NET Core 中间件(Middleware)入门

    一.前言 1.本教程主要内容 ASP.NET Core 中间件介绍 通过自定义 ASP.NET Core 中间件实现请求验签 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10 SD ...

  9. harbor API 与tag 清理

    harbor API 官方swagger swagger在线查看 harbor tag 清理 python程序 import requests import json class RequestCli ...

  10. C语言Ⅰ博客作业09

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/10029 我在这个课程的 ...