js中的apply方法和call方法区别

来源:互联网 发布:检测 android ios js 编辑:程序博客网 时间:2024/06/16 23:40

最近做了一些前端面试题,才发现自己的基础知识不是那么好,我把apply方法和call方法弄混了,查了很多资料,现在终于弄明白了。下面我说说我的一些心得。
首先要弄明白以下几个问题:
(1)apply和call是干什么的?apply和call的区别与联系?
(2)什么情况下用apply,什么情况下用call?



下面我来一一解决:

(1)

apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

call方法
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。arg1[, arg2[, [,.argN]]]]]是一个参数列表。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

实例:

apply方法

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

分析:
Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“qian”,”21”,”一年级”];
也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面

call方法

<script type="text/javascript">     /*定义一个人类*/      function Person(name,age)      {          this.name=name;          this.age=age;      }     /*定义一个学生类*/      functionStudent(name,age,grade)    {         Person.call(this,name,age);         this.grade=grade;     //创建一个学生类     var student=new Student("qian",21,"一年级");     //测试     alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);     //大家可以看到测试结果name:qian  age:21  grade:一年级 </script>


(2)
- 在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));
- 细心的人可能已经察觉到,在我调用apply方法的时候,第一个参数是对象(this), 第二个参数是一个数组集合, 在调用Person的时候,它需要的不是一个数组,但是为什么他给我一个数组我仍然可以将数组解析为一个一个的参数,这个就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) 这个如果让我们用程序来实现将数组的每一个项,来装换为参数的列表,可能都得费一会功夫。


补充:

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("1","2","3"); vararr2=new Array("4","5","6"); Array.prototype.push.apply(arr1,arr2);

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

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

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

对普通函数调用,我们通常把this绑定为null。

装饰器

利用apply(),我们还可以动态改变函数的行为。

JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数。

现在假定我们想统计一下代码一共调用了多少次parseInt(),可以把所有的调用都找出来,然后手动加上count += 1,不过这样做太傻了。最佳方案是用我们自己的函数替换掉默认的parseInt():

var count = 0;var oldParseInt = parseInt; // 保存原函数window.parseInt = function () {    count += 1;    return oldParseInt.apply(null, arguments); // 调用原函数};// 测试:parseInt('10');parseInt('20');parseInt('30');count; // 3

split(),与join()方法正好相反

split()方法是将字符串分割成字符串数组

<script type="text/javascript">var str="How are you doing today?"document.write(str.split(" ") + "<br />")document.write(str.split("") + "<br />")document.write(str.split(" ",3))</script>

输出:

How,are,you,doing,today?H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?How,are,you

**join()**join() 方法用于把数组中的所有元素放入一个字符串。
元素是通过指定的分隔符进行分隔的。

<script type="text/javascript">var arr = new Array(3)arr[0] = "George"arr[1] = "John"arr[2] = "Thomas"document.write(arr.join("."));document.write(arr.join());</script>

输出:

George.John.ThomasGeorge,John,Thomas
0 0
原创粉丝点击