call()和apply()函数
1.作用:扩展函数的作用域(上下文)-- 即this值
上面这句话是来自http://www.jb51.net/article/30883.htm这篇文章的,我觉得很精确的描述出call和apply的作用
eg:
var name = 1;
var obj = {name:"12"}
function a(){
name = this.name;
console.log(name);
console.log(this);
}
function b(){
a.call(obj);
}
b();
最后输出的是:
本来函数a的作用域(this)指向的是window/Global 对象,但是通过a.call(obj)之后,把a的作用域(this指向)变成了obj,我认为可以理解为调用
b(){
var x1=0;
a.call(this,x1);
}
就可以理解为在b函数中调用函数a,并且把b的变量x1给a使用
2.call和apply的区别:
语法:
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
apply([thisObj[,argArray]])
假如传入的参数形式是数组的话,那就使用apply,如果传入的是参数列表并且位置一一对应,那就使用call
eg:
person(name,age){
this.name = name;
this.age = age;
}
student(name,age,grade){
person.apply(this,arguments);
this.grade = grade;
}
teacher(age,name,sex){
person.call(this,name,age);
this.sex = sex;
}
看到区别了吗?person里面的参数顺序是name,age,student里面的顺序是name,age,grade,因为person里面需要2个参数,所以他会自动把student的前2个参数传进去。
但是teacher的参数是age,name,sex,因此在调用时使用的是apply,传入数据时再按teacher的参数顺序把person的参数传进去
3.apply的更多用法(案例):数组中得出最大的数 -- 调用Math.max()
以下案例源自大神文章:http://www.jb51.net/article/44875.htm
<SPAN style="FONT-SIZE: 18px">alert(Math.max(5,8)); //8
alert(Math.max(5,7,9,3,1,6)); //9
//但是Math.max的参数都是一个个单独的数字,在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1];
alert(Math.max(arr)); // 这样却是不行的。NaN
//不用apply要这样写
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
alert(getMax(arr)); //9
//换用apply,可以这样写
function getMax2(arr){
return Math.max.apply(null,arr);
}
alert(getMax2(arr)); //9
//两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。
//再比如数组的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
//如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[1,3,4,3,4,5]
//arr1.push(arr2)显然是不行的。 因为这样做会得到[1,3,4,[3,4,5]]
//我们只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身)
var arrLen=arr2.length;
for(var i=0;i<arrLen;i++){
arr1.push(arr2[i]);
}
//自从有了Apply,事情就变得如此简单
Array.prototype.push.apply(arr1,arr2); //现在arr1就是想要的结果
alert(Math.max(5,7,9,3,1,6)); //9
//但是Math.max的参数都是一个个单独的数字,在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1];
alert(Math.max(arr)); // 这样却是不行的。NaN
//不用apply要这样写
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
alert(getMax(arr)); //9
//换用apply,可以这样写
function getMax2(arr){
return Math.max.apply(null,arr);
}
alert(getMax2(arr)); //9
//两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。
//再比如数组的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
//如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[1,3,4,3,4,5]
//arr1.push(arr2)显然是不行的。 因为这样做会得到[1,3,4,[3,4,5]]
//我们只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身)
var arrLen=arr2.length;
for(var i=0;i<arrLen;i++){
arr1.push(arr2[i]);
}
//自从有了Apply,事情就变得如此简单
Array.prototype.push.apply(arr1,arr2); //现在arr1就是想要的结果
</SPAN>
部分内容源自:
因为都是看了好几篇文章自己的一些记录下来的知识点,如果没有标明哪个大神的网站可以跟我讲!