call方法

  总的来说call方法有这几种作用:1.可以借用另一个对象的方法。2.改变this的指向(重要)。3.将arguments数组化。下面详细介绍这三种作用:

  1.可以借用另一个对象的方法:当一个对象需要借用另一个对象的方法时,此时需要用到call方法。

     //对象1
var myclass={
getNumbers:function(sum,sum1){
return sum+sum1;
}
};
//对象2
var student={
getDetail:function(){
return {name:'张三',habits:'打篮球'}
}
};
//借用
console.log(myclass.getNumbers.call(student,10,200)); //

这里student对象想要借用myclass对象中的getNumbers方法,需要借用谁的,就将它写在前头。这样就可以实现调用,需要注意的是函数也是对象,同样可以用call方法。

  2.改变this的指向(重要)。

  先来看个例子:  用户名:<input type="text" id=“text" value="张三" />

 var value="李四";
//函数中默认this指向window
function fn1(){
console.log(this.value);
}
fn1();//李四

可以看出此时要想获得表单中的value值是获取不到的。那要如何才能获取到呢,这时call的作用就体现出来了。可以用以下方式获取:

 function fn1(){
console.log(this.value);
}
fn1.call(document.getElementById('text')); //张三

这个时候this指向input元素对象。

总结一下:call是函数下的一个方法,call方法的第一个参数可以改变函数执行过程中内部this的指向,第二个参数开始就是原来函数的参数列表。

3.将arguments数组化。

  这里先简单介绍一下什么是arguments:arguments是一个数组对象,用于保存函数的参数,准确点说应该是一个伪数组,你可以使用arguments对象在函数中引用函数的参数,它只有在代码运行的时候才起作用。如:

 function add() {
var sum = 0,
len = arguments.length;
for (var i = 0; i < len; i++) {
sum += arguments[i];
}
return sum;
}
console.log(add()); //
console.log(add(1)); //
console.log(add(1, 2, 3, 4)); //

前面说arguments是一个伪数组,那什么是伪数组,伪数组就是它类似于数组,但除了length属性和索引元素之外没有任何数组的属性方法,比如没有push方法。在JavaScript中arguments和通过document获取的dom集合都属于伪数组。

  所以我们很有必要将这些伪数组转换成真数组以便可以使用数组的属性方法。我们可以用call方法将它转换成一个真正的数组:Array.prototype.slice.call(arguments)。利用这个固定用法就可以实现,用一个例子说明一下。

 function add(){
var sum=0;
/*arguments.push(10) //直接这样写则会报错*/
var arr = Array.prototype.slice.call(arguments)
arr.push(10)
for(var i=0;i<arr.length;i++){
sum+=arr[i]
}
return sum;
} var sum = add(1,2,3,4,5) console.log(sum) //

apply方法

  其实apply方法与call方法的作用是一样的,他们的不同点在于:接收参数的方式不一样。apply方法的第一个参数与call一样,第二个参数是一个参数数组,而call方法传递给函数的参数必须列举出来,还是上面那个例子:

 1     //对象1
2 var myclass={
3 getNumbers:function(sum,sum1){
4 return sum+sum1;
5 }
6 };
7 //对象2
8 var student={
9 getDetail:function(){
10 return {name:'张三',habits:'打篮球'}
11 }
12 };
13 //借用
14 console.log(myclass.getNumbers.call(student,10,20)); //20
15 console.log(myclass.getNumbers.apply(student,[10,10)]); //

那么我们在什么情况下用apply,什么情况下用call呢?如果参数形式是数组的时候,比如传递参数arguments这种数组类型的,并且他们的参数列表是一一对应的就可以采用apply方法。若参数列表不一致,比如getNumbers的参数列表是(sum,sum1),而student的参数列表是(10,10,20)的,这样就可以用call方法,当然apply的作用不止这些。

apply的其他用法

  1.利用Math.max()函数和Math.min()函数获取数组的最大最小值。我们知道JavaScript中的Math.max()函数,接收的是任意个参数:

console.log(Math.max(1,5,9,2,7,6)) //

但在很多情况下,我们需要找到数组中的最大元素。想这么写肯定是不行的:

var arr=[2,4,9,1]
console.log(Math.max(arr))

我们传统的方法是遍历每一个元素:

 function getMax(arr){
for(var i=0,max=arr[0];i<arr.length;i++){
max=Math.max(max,arr[i]);
}
return max;
}
console.log(getMax([1,3,5,6])); //

这么写比较低效,换成apply:

 function getMax2(arr){
return Math.max.apply(null,arr);
/* return Math.max.call(null,1,3,5,6);*/
}
console.log(getMax2([1,3,5,6])) //

这样明显效率要高很多。

  2.将一个数组合并到另一个数组中。我们传统写法是这样的:

     var arr1=new Array("1","2","3");
var arr2=new Array("4","5","6"); function PushArray(arr1,arr2){
for(var i=0;i<arr2.length;i++){
arr1.push(arr2[i])
}
return arr1;
}
var result = PushArray(arr1,arr2);
console.log(result); //["1", "2", "3", "4", "5", "6"]

换成apply方法需要这么写: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);

apply用的多是因为函数可以接收不限个参数,这样我们就只能使用arguments老管理可变参数,比如max min push join split replace等方法,apply虽然传递的是数组,但是使用的时候是把数组拆开的。

  3.apply不仅仅是使用上面列到的几个函数而已,它还有更加高层的用途:

 function add(a, b) {
return a + b;
} function add(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i]
}
return sum;
} var sum = add(1,2,3,4,5)
console.log(sum); // //如何计算数组的和
var sum2 = add.apply(null,[1,2,3,4,5])
console.log(sum2); //

有什么不足的请指出。

改变

理解JavaScript中的call和apply方法的更多相关文章

  1. 简单理解Javascript中的call 和 apply

    javascript中面向对像的能力是后来加进来的, 为了兼容性, 所以整出了很多奇特的东西, function Animal(){ this.name = "Animal"; t ...

  2. javascript中的call()和apply()方法的使用

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

  3. 浅谈javascript中的call与apply方法

    call方法与apply方法都是为了改变函数体内部this的指向. call方法与apply方法,这二者的作用完全一样,只是接受参数的方式不太一样. apply()方法: Function.apply ...

  4. 浅谈javascript中的call()和apply()方法

    话说在js中,每个函数都包含两个非继承而来的放方法,apply()和call(),使得我们能在特定的作用域中调用函数. 官方定义: 语法:       fun.call(thisArg[, arg1[ ...

  5. Javascript中call方法和apply方法用法和区别

    第一次在博客园上面写博客,知识因为看书的时候发现了一些有意思的知识,顺便查了一下资料,就发到博客上来了,希望对大家有点帮助. 连续几天阅读<javascript高级程序设计>这本书了,逐渐 ...

  6. 理解JS中的call、apply、bind方法(*****************************************************************)

    在JavaScript中,call.apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向. call.apply.bind方法的共同点和区别:app ...

  7. 【原】理解javascript中的this

    最近的文章基本都是总结javascript基础内容的,因为我觉得这些东西很重要.而且很多时候你觉得你理解了,其实并没有你自认为的那么理解.十月份没怎么写文章,因为国庆出去玩的比较久,心变野了,现在是时 ...

  8. js笔记——理解js中的call及apply

    call及apply在js里经常碰得到,但一直感觉很陌生,不能熟练使用.怎样才能熟练应用呢? 为什么存在call和apply? 在javascript OOP中,我们经常会这样定义: function ...

  9. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

随机推荐

  1. python爬微信公众号前10篇历史文章(5)-JSON相关内容小结

    json - JSON encoder and decoder JSON: JavaScript object notation,是一种轻量级的数据交换格式.JSON 是 JS 对象的字符串表示法,它 ...

  2. 请详细描述(以硬盘启动)Linux系统从打开主机电源到进入登录界面整个过程的流程。

    1. 开机进行BIOS(BIOS(Basic Input / Output System)自检测系统外围硬件设备如CPU.内存.IO.显卡.鼠标键盘等.根据BIOS中设置的系统启动顺序搜索用于启动系统 ...

  3. 来自后端的突袭? --浅尝最新开源的C# Web引擎 Blazor

    在今年年初, 恰逢新春佳节临近的时候. 微软给全球的C#开发者们, 着实的送上了一分惊喜. 微软正式开源Blazor ,将.NET带回到浏览器. 这个小惊喜, 迅速的在dotnet开发者中间传开了. ...

  4. 简单使用git和github来管理代码----配置与使用

    在以前没听说过github之前,自己写的代码很容易丢或者遗失,等到用时才知码到用时方恨丢,现在用了github,真的是替自己生省不少的事,闲话不多说,上教程. 1 在github上注册账号 https ...

  5. 笔记:Spring Boot 配置详解

    Spring Boot 针对常用的开发场景提供了一系列自动化配置来减少原本复杂而又几乎很少改动的模板配置内容,但是,我们还是需要了解如何在Spring Boot中修改这些自动化的配置,以应对一些特殊场 ...

  6. 前端的UI设计与交互之字体篇

    跨平台的字体设定,力求在各个操作系统下都有最佳展示效果.字体是界面设计中最重要的基本构成之一,用户通过文本来消化内容和完成工作,优雅的字体将大大提升用户的阅读体验及工作效率.在满足不同终端始终保持良好 ...

  7. CXF 开发 REST 服务

    今天我们将视角集中在 REST 上,它是继 SOAP 以后,另一种广泛使用的 Web 服务.与 SOAP 不同,REST 并没有 WSDL 的概念,也没有叫做"信封"的东西,因为 ...

  8. Kali Linux下安装Nessus扫描器

    一.官网下载Nessus(http://www.tenable.com/products/nessus/select-your-operating-system),这里需要查找自己对应的版本,如下图一 ...

  9. Spring学习笔记四 整合SSH

    三大框架架构(整合原理) 步骤1:导包 Hibernate包 1.Hibernate包,hibernate/lib/required 2.hibernate/lib/jpa | java persis ...

  10. 基于 HTML5 Canvas 实现的文字动画特效

    前言 文字是网页中最基本的元素,一般我们在网页上都是展示的静态文字,但是就效果来说,还是比较枯燥的.文字淡入淡出的动画效果在项目中非常实用,如果有某些关键的文字,可以通过这种动态的效果来提醒用户阅读. ...