js call和apply的区别别 面试

理解apply()和call()方法
apply()和call()都属于函数对象的方法,因此所有函数都可以用这两个方法。
apply()方法用于解决这样一个问题:一个对象如何调用不属于它的方法?
function add(i, j){
&&& console.log(i + j);
对象o如何调用add方法?最简单的思路是直接将add方法添加到对象o中。
这样就可以调用了
o.plus(o.a, o.b); // 3
这么做的问题是对象o被修改了,不好。那么如何在不修改对象o的前提下实现此目的呢?答案就是使用apply()。
add.apply(o, [o.a, o.b]); // 3
apply()的作用可以理解为:将某个方法应用到某个对象上。
所有方法(函数)的调用一定是作为某个对象的方法进行调用的,apply()就是用于指定调用函数的对象。
apply()接收两个实参,第一个就是指定的对象,或者是this。this表示apply()执行时的作用域环境,如果是在全局环境下调用apply(),那么this指全局对象,如果是在局部环境下(也就是某个函数里)调用,那么this指该局部环境(也就是某个函数的作用域)。如果传入的参数是null或undefined,会被自动转换为全局对象。
假设上述代码都在全局环境下,那么下列三种写法是一样的:
add.apply(o, [o.a,o.b]); // 3, 由对象o调用
add.apply(this, [o.a,o.b]); // 3, 在全局作用域下调用(或者说在Global/window对象上调用)
add.apply(null, [o.a,o.b]); // 3, 在全局作用域下调用(或者说在Global/window对象上调用)
但是!在ES5严格模式下,无论第一个参数传入的是什么,都会被统一的转换为this,即第一个参数只能是this。
第二个参数是调用函数时所传入的参数,必须是一个数组,或者直接传入arguments对象。可选填。
call()方法的作用和apply()是完全一样的,其区别仅在于call()的参数写法不同,除第一个参数和apply是一样的,而其余参数需要逐一列举出来。
add.call(o, o.a, o.b); // 3
有了apply和call,我们可以将函数指派给任何对象,或者说任何对象都能够调用任何函数(道理上没错,至于能不能起作用,完全取决于实际代码)。
简单总结:
foo.call(this,&arg1,arg2,arg3)&==&foo.apply(this,&arguments) == this.foo(arg1,&arg2,&arg3)
来看一个实用案例:
求数组中的最大/最小值
var arr = [1, 2, 3]; // 数组对象本身没有求最大/最小值的方法,因此借用Math对象的方法
var maxNum = Math.max.apply(this,arr); // 只能用apply,不能用call
console.log(maxNum); // 3
apply和call还可以实现对象之间的继承。显然,对象应该由构造函数的形式创建,才能运用这两个方法。
这里借用了阮一峰老师的例子。
// 一个"动物"对象
function Animal(){
this.species = "动物";
// 一个"猫"对象
function Cat(name, color){
this.name =
this.color =
// 在"猫"的构造函数中绑定"动物"
function Cat(name, color){
Animal.apply(this); // Animal中的this现在指向Cat
this.name =
this.color =
// 构造一个实例,看看"猫"是否继承了"动物"的属性
var cat = new Cat("大毛", "黄色");
alert(cat.species); // 动物,说明"猫"继承了"动物"的属性
这些简单例子仅能帮助理解apply和call的基本用法,要想熟练使用,发挥其真正的威力,还得多看高手源码、多实践。
这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我只写那些我还没有完全掌握的东西,那些我精通的东西,往往没有动力写.炫耀从来不是我的动机,好奇才是.& 对于这句话,不能赞同更多,也让我下决心好好写这篇 ...
对于alias, alias_method, alias_method_chain的深入理解是有益的,因为rails3的源码里很多地方使用了alias_method_chain的魔法. 有人评论说alias_method_chain使用的过多不好,具体怎么不好,是后话了,这篇文章集中在理解这3个方法上面.如果想转载本文,请注明出处,谢谢!请尊重别人的劳动成果 ...
总结的文章略长,慎点. 知识点预热 引用类型:引用类型的值(对象)是引用类型的一个实例.在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起.在其他面向对象语言中被称为类,虽然ECMAScript从技术上讲也是一门面向对象语言,但它不具备传统面向对象语言所支持的类和接口等基本结构而是通过别的形式实现类模板和继承.引用类型描述的是一类对 ...
很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习js更是大有裨益. 而更多的题目是我一路以来收集的,也有往年的,答案不确保一定正确,如有错误或有更好的解法,还请斧正. 附上第二篇:BAT及各大互联网公司2014前端笔试面试题--Html,Css篇 前面几题是会很基础,越下越有深度. 初级Ja ...
我们都知道,在JavaScript中只能模拟实现OO中的&类&,也就意味着,在JavaScript中没有类的继承.我们也只能通过在原对象里添加或改写属性来模拟实现. 先定义一个父类, 1 //父类 2 function ParentClass() { 3 this.className = &ParentClass&;
1.基本知识
os.path在不同的环境中设置文件的路径时作用非常大,我们经常在Django或Flask中都看到它的身影,常用的其实有下面的几个方法:常用方法作用os.path.dirname(__file__)返回当前python执行脚本的执行路径(看下面的例子),这里__file__为固定参数os.path.abspath(file)返回一个文件在 ...
© CopyRight
Inc All Rights Reserved.
管理员邮箱: info @JS apply与call的理解 (希望能帮到对二者迷糊的盆友)
看书的时候总是看到apply和call的使用,自己也查了好多文档,总是感觉说的很深自己理解不了。最近看到一篇文章再加上请教别人总算懂了点,
所以做个笔记以后和大家分享,也方便自己查阅...如果有表述不清楚的或是不明确的地方希望各位大神能够提点~
此文是借鉴其他文章加自己的一些练习
主要解决以下几个问题:
1、apply和call的区别在哪里
2、什么情况下用apply,什么情况下用call
3、apply的其他巧妙用法(一般在什么情况下可以使用apply)
首先apply的定义如下:
apply方法能劫持另外一个对象的方法,继承另外一个对象的属性
Function.apply(obj,args)方法能接收两个参数
& & obj:这个对象将代替Function类里this对象
& & args:这个是数组,它将作为参数传给Function(args--&arguments)
1.apply示例
javascript 代码效果预览//定义一个人类
function Person(name,age){
this.name =
this.age =
//定义一个学生类
function Student(name,age,grade){
Person.apply(this,arguments);
this.grade =
//创建一个学生类
var student = new Student('谜','10','一年级');
console.log('name:'+student.name+'age:'+student.age+'grade:'+student.grade);
结果如下:
name:谜age:10grade:一年级
学生类里没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处。 分析:Person.apply(this,arguments);
this:代表的是student,表示将Person中的this指向student。
arguments:是一个数组,在例子中表示['谜','10','一年级'];
通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的
语句,这样就讲属性创建到了student对象里面
2.call示例
在Student函数里面可以将apply中修改成如下: Person.call(this,name,age);
这样就可以了。 所以call和apply的区别是传参的格式
apply是arguments对象作为参数,而call则是要把需要传的参数一一列出。
3.什么情况下用apply,什么情况下用call
在给对象参数的情况下,如果参数的形式是数组时候,并且参数列表相同则使用apply
例:apply示例里面传递了参数arguments这个参数是数组类型,并且在调用Person的
时候参数的列表是对应一致的,也就是Person和Student的参数列表前两位是一致的,就可以采用apply。
如果我的Person的参数列表是这样的(age,name)而Student的参数列表是(name,age,grade),
这样的就可以用call来实现了Person.call(this,age,name,grade);
4.apply的一些其他巧妙用法
在调用apply方法的时候第一个参数是对象(this),第二个参数是一个数组集合,
在调用Person的时候,他需要的不是一个数组,但是为什么我给他一个数组他仍然可以将数组解析为一个一个的参数?
这就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表。如果用程序实现将数组的每一项来转换为
参数的列表可能得费一会时间,而借助apply的这点特性就有了高效的方法,见下方例子
a)Math.max可以实现得到数组中的最大的一项
因为Math.max参数里不支持数组,只支持类似于Math.max(param1,param2,param3)这种,所以可以利用apply来实现
见证奇迹的时刻~~~~~~~
javascript 代码效果预览var a = [1,21,3,12,2];
console.log(Math.max.apply(Math,a));
原理就是apply()方法将数组a转换为一个一个的参数进行比较最后返回最大值
最大值可以做到最小值当然也可以
javascript 代码效果预览var a = [1,21,3,12,2];
console.log(Math.min.apply(Math,a));
b)Array.prototype.push可以实现两个数组合并
因为push方法没有提供push一个数组,但是提供了push(param1,param2...)所以也可以通过apply来转换一下数组:
javascript 代码效果预览var arr1 = new Array('1','3','4');
var arr2 = new Array('6','7','8');
Array.prototype.push.apply(arr1,arr2);
console.log(arr1);
原理:arr1调用了push方法参数是通过apply将数组装换为参数列表的集合。
看到这里大家是不是心里想说:有必要这么麻烦吗(嫌弃的表情)js明明就有concat 这个强大的方法,
concat() 方法用于连接两个或多个数组。
该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。,如下
javascript 代码效果预览var arr1 = new Array('1','3','4');
var arr2 = new Array('6','7','8');
console.log(arr1.concat(arr2));
console.log(arr1);
console.log(arr2);
其实我想说如果真的需要数组链接的话当然要用concat啊,使用apply只是介绍一下可以这么用并不是只能这么用~~嘿嘿
一开始我对apply真的是很蒙圈,最后多看了几遍,然后敲了几遍代码,有点了解了。
所以,不管做什么事情,一定要自己多敲代码,哪怕只是照着书本敲也会有多领悟的~~
9 总笔记数
2.4万 总阅读量
Copyright &
All Rights Reserved.
合作伙伴:关于call()和apply()方法的一点心得 - 博客频道 - CSDN.NET
木溪的随笔
向多隆看齐
向多隆学习
向多隆靠拢
分类:JavaScript
1. 这两个是JS原生方法;
2. 自我理解:这个给“懒人”准备的方法;
3. 举例(重点):
//example 1:
function Person(name, age)
&&& &&& &&& &&& this.name =
&&& &&& &&& &&& this.age =
&function Student()
&&& &&& & //do nothing
&var stu = new Student();
alert('name: ' + stu.name + '\n' + 'age: ' + stu.age); // name: undefined& age:undefined
小结:以上未能弹出学生的姓名和年龄信息,因为我们在学生的类里什么都没做。
//example 2:
function Person(name, age)
&&& this.name =
&&& this.age =&&& &&& &&&
&}&& &&& &&&
&function Student()
&&& & Person.apply(this, arguments);
&}&& &&& &&&
var stu = new Student('Tom', 21);
alert('name: ' + stu.name + '\n' + 'age: ' + stu.age); // name: Tom age: 21
//example 3:
function Person(name, age)
& this.name =&& &&& &&& &&
& this.age = &&& &&& &&&
&}&& &&& &&&
&function Student()& &&& &&&
&&&& Person.call(this, 'Tom', 21);
& var stu = new Student();
& alert('name: ' + stu.name + '\n' + 'age: ' + stu.age);//name: Tom age: 21
1. 当Student类中什么都没有时,仍然想要显示学生的姓名和年龄,那么就要借用Person类中的方法来实现。
2. 如何借用?使用apply()或者call(), 因为Person中有name和age两个属性,借过来用的话,Student类中当然也就有
&&& 了name和age属性啊!在创建好学生类的实例后,就可以使用name和age属性了。
3. apply()和call()有和区别?二者的区别在于参数的不同。apply()中使用的是arguments, 一般适合参数不确定的时候使用;
&&& call()中给定要传的参数,一般个数上来说是一定的。
总的来说,当你想用一个方法,但是这个方法自身没有,而你刚好又知道谁有这个方法,这个时候就可以使用上述的方法,把别人的东西拿来为我所用。
排名:千里之外
(6)(0)(1)(3)(2)(2)(1)(4)(1)(1)(2)你正在使用的浏览器版本过低,将不能正常浏览和使用知乎。}

我要回帖

更多关于 js apply call 区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信