老生常谈javascript之call,apply的区别

D一生

刚开始看到javascript的函数apply和call时,非常的模糊,不知所云,然后看书,网上查询多少知道点了眉目,下面是我做的笔记,希望和大家分享,有不对之处希望各位多多指正,共同进步。。。
本文将从三个方面介绍apply,call的用法

1. apply,call的定义和区别
2. 什么情况下使用apply,什么情况下使用call
3. 巧用apply

  1. apply,call的定义和区别
    apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
    Function.apply(obj,args)方法能接收两个参数
    obj:这个对象将代替Function类里this对象(就是定义函数代码块里面的this)
    args:这个是数组,它将作为参数传给Function(args-->arguments),这个可以是数组也可以是 arguments

    call和apply的意思一样,唯一不同的是接受的参数不同,
    Function.call(obj,[param1[,param2[,…[,paramN]]]])
    obj:这个对象将代替Function类里this对象
    params:这个是一个参数列表

    aplly示例
    //定义一个Animal的类
    function Animal(name,age){

       this.name = name;
       this.age = age;

    }
    //定义一个cat类
    function Cat(name,age,kind){

       Animal.apply(this,arguments);//调用Animal的方法,并将里面的this,转换成Cat实例
       this.kind = kind;

    }
    var cat = new Cat('yingwu',4,'cat');

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

call示例,将上面代码变成call就是
Animal.call(this,name,age)//其他的保持不变,这就是差uncanbutong

  1. 什么情况下用apply,什么情况下用call

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

  • apply的一些其他巧妙用法
    通过以上示例可以看出apply可以讲一个数组默默的解析成一个一个的参数,可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) ,利用aplly这个特点我们就可以用在一些针对字符串操作的方法了:例如
    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过去(利用Math方法但是不改变this的指向)

    b) Math.max 可以实现得到数组中最大的一项
    和 max是一个原理 var min=Math.min.apply(null,array);
    c) Array.prototype.push 可以实现两个数组合并

var arr1=new Array("1","2","3");

var arr2=new Array("4","5","6");

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

**

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

**
一般在目标函数只需要n个参数列表,而不接收一个数组的形式([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙地解决这个问题!
末尾略微提一下bind方法是ES5新出的,它主要是绑定函数内部的this,示例

window.color = "red";
var o = { color: "blue" };
function sayColor(){

alert(this.color);

}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
//讲this绑定在o对象上,所以sayColor里面的this.color就指向哦,即使全局调用ojectSayColor依旧输出blue
支持bind()方法的浏览器有 IE9+、Firefox 4+、Safari 5.1+、Opera 12+、 Chrome

总结,这个一定要多敲代码,理解,目前我的理解是aplly,call都是调用别人的方法并且讲方法里面的this改变,两者传参数不同,正因为传参数不同,所以可以用aplly用在一些目标函数只需要接受n个参数列表,而不接受数组的函数里面,文章中部分内容参考自http://www.cnblogs.com/xiaoho...,也添加了自己的理解,不对之处还望各位多多指正

阅读 7.4k

菜鸟论前端
分享工作中的前端知识和经验;分享新技术,共同探讨前端的发展趋向,共同研究新技术,fighting

一如前端深似海

232 声望
15 粉丝
0 条评论

一如前端深似海

232 声望
15 粉丝
宣传栏