刚开始看到javascript的函数apply和call时,非常的模糊,不知所云,然后看书,网上查询多少知道点了眉目,下面是我做的笔记,希望和大家分享,有不对之处希望各位多多指正,共同进步。。。
本文将从三个方面介绍apply,call的用法
1. apply,call的定义和区别
2. 什么情况下使用apply,什么情况下使用call
3. 巧用apply
-
apply,call的定义和区别
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象(就是定义函数代码块里面的this)
args:这个是数组,它将作为参数传给Function(args-->arguments),这个可以是数组也可以是 argumentscall和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
- 什么情况下用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...,也添加了自己的理解,不对之处还望各位多多指正
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。