1. 每个函数都包含两个非继承而来的方法:call()方法和apply()方法。

2. 相同点:这两个方法的作用是一样的。

都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。

call()方法使用示例:

    //例1
 <script>
window.color = 'red';
document.color = 'yellow'; var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
} changeColor.call(); //red (默认传递参数)
changeColor.call(window); //red
changeColor.call(document); //yellow
changeColor.call(this); //red
changeColor.call(s1); //blue </script> //例2
var Pet = {
words : '...',
speak : function (say) {
console.log(say + ''+ this.words)
}
}
Pet.speak('Speak'); // 结果:Speak... var Dog = {
words:'Wang'
} //将this的指向改变成了Dog
Pet.speak.call(Dog, 'Speak'); //结果: SpeakWang

apply()方法使用示例:

    //例1
<script>
window.number = 'one';
document.number = 'two'; var s1 = {number: 'three' };
function changeColor(){
console.log(this.number);
} changeColor.apply(); //one (默认传参)
changeColor.apply(window); //one
changeColor.apply(document); //two
changeColor.apply(this); //one
changeColor.apply(s1); //three </script> //例2
function Pet(words){
this.words = words;
this.speak = function () {
console.log( this.words)
}
}
function Dog(words){
//Pet.call(this, words); //结果: Wang
Pet.apply(this, arguments); //结果: Wang
}
var dog = new Dog('Wang');
dog.speak();

3. 不同点:接收参数的方式不同。

  • apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。

语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。

说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个 
TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。

  • call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。

语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。

说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。

使用示例1:

 function add(c,d){
return this.a + this.b + c + d;
} var s = {a:, b:};
console.log(add.call(s,,)); // 1+2+3+4 = 10
console.log(add.apply(s,[,])); // 1+2+5+6 = 14

使用示例2:

    <script>
window.firstName = "Cynthia";
window.lastName = "_xie"; var myObject = {firstName:'my', lastName:'Object'}; function getName(){
console.log(this.firstName + this.lastName);
} function getMessage(sex,age){
console.log(this.firstName + this.lastName + " 性别: " + sex + " age: " + age );
} getName.call(window); // Cynthia_xie
getName.call(myObject); // myObject getName.apply(window); // Cynthia_xie
getName.apply(myObject);// myObject getMessage.call(window,"女",); //Cynthia_xie 性别: 女 age: 21
getMessage.apply(window,["女",]); // Cynthia_xie 性别: 女 age: 21 getMessage.call(myObject,"未知",); //myObject 性别: 未知 age: 22
getMessage.apply(myObject,["未知",]); // myObject 性别: 未知 age: 22 </script>

4、什么情况下用apply,什么情况下用call

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

<script type="text/javascript">
/*定义一个人类*/
function Person(name,age)
{
this.name=name;
this.age=age;
}
/*定义一个学生类*/
functionStudent(name,age,grade)
{
Person.apply(this,arguments); //Person.call(this,name,age);
this.grade=grade;
}
//创建一个学生类
var student=new Student("zhangsan",,"一年级");
//测试
alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
//大家可以看到测试结果name:zhangsan age:21 grade:一年级
//学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.
</script>

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来装换一下这个数组,即:

vararr1=new Array("","","");  

vararr2=new Array("","","");  

Array.prototype.push.apply(arr1,arr2);  

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

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

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

 

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

  1. JS中的call()方法和apply()方法用法总结

    原文引自:https://blog.csdn.net/ganyingxie123456/article/details/70855586 最近又遇到了JacvaScript中的call()方法和app ...

  2. JS中的call()方法和apply()方法用法总结(挺好 转载下)

    最近又遇到了JacvaScript中的call()方法和apply()方法,而在某些时候这两个方法还确实是十分重要的,那么就让我总结这两个方法的使用和区别吧. 1. 每个函数都包含两个非继承而来的方法 ...

  3. [转] JS中的call()方法和apply()方法用法总结

    //例1 <script> window.color = 'red'; document.color = 'yellow'; var s1 = {color: 'blue' }; func ...

  4. 关于JAVASCRIPT call 方法和 apply 方法性能对比

    JavaScript 关于call 方法和 apply 方法常用形式 call obj.call(object, args , ....); apply obj.apply(object, [args ...

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

    最近又遇到了JacvaScript中的call()方法和apply()方法,而在某些时候这两个方法还确实是十分重要的,那么就让我总结这两个方法的使用和区别吧. 1. 每个函数都包含两个非继承而来的方法 ...

  6. call方法和apply方法

    1.call 语法 call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 参数 thisObj  可选项.将被用作当前对象的对象. arg1,arg2, , argN  ...

  7. js中得call()方法和apply()方法的用法

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

  8. 《ES6基础教程》之 Call 方法和 Apply 方法

    <script type="text/javascript"> // Call方法: // 语法:call(thisObj[,arg1,arg2,...,argN]) ...

  9. js中call()方法和apply方法的使用

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

随机推荐

  1. Go语言学习之常量(The way to go)

    生命不止,继续go go go . 上一篇博客<Go语言学习之变量(The way to go)介绍了go中的变量,今天就介绍常量. const关键字 跟c++中一样,go中同样具有const关 ...

  2. Mybatis中接口和对应的mapper文件位置配置深入剖析

    首先要说明的问题是,Mybatis中接口和对应的mapper文件不一定要放在同一个包下,放在一起的目的是为了Mybatis进行自动扫描,并且要注意此时java接口的名称和mapper文件的名称要相同, ...

  3. Matlab绘图基础——图形绘制的插值  以及 图像大小的重采样

    使用说明:图形绘制时的插值 interp1   %1-D data interpolation interpft  %使用fft算法插值     %将原数据x转换到频率域,再逆转换回来更密集的数据采样 ...

  4. java基础(3)--8种基本类型

    八种基本类型 数据类型分为两大类:基本类型,引用类型 基本类型有8种,除了基本类型(8种)以外任何类型都是引用类型.如: String 是引用类型 基本类型有8种(首字母是小写): 整数:byte, ...

  5. mysql 创建数据库 并设置utf8格式

    CREATE DATABASE `database` CHARACTER SET utf8 COLLATE utf8_general_ci; 设置utf8之后,不容易出现中文乱码.

  6. JNI_Z_01_获取Clazz

    1. 为了能够在C/C++中使用Java类,jni.h头文件中专门定义了jclass类型来表示Java中的Class类(ZC: 就是Clazz) 2. 2.1.JNIEXPORT void JNICA ...

  7. $1...$9 属性 (RegExp) (JavaScript)

    返回在模式匹配期间找到的,所存储的最近的九个部分. 只读.     RegExp.$n 参数     RegExp 始终为全局 RegExp 对象. n 1 至 9 之间的任意整数. 备注     每 ...

  8. LightOJ - 1265 概率

    题意:有t头老虎,d头鹿,每天五种情况,虎虎,虎鹿,鹿鹿,鹿人,人虎,求生存的概率 题意:鹿就是来迷惑你的(结果我就陷进坑了),无论怎么选最后一定只剩下虎虎,虎人两种情况对结果有影响,那么如果有n只虎 ...

  9. 【lightoj-1063】Ant Hills(求割点)

    求割点模板题 #include <bits/stdc++.h> using namespace std; const int N = 10004; int dfn[N], low[N]; ...

  10. JAM计数法(模拟)

    题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字 ...