call和apply的作用和区别:
每个函数都包含两个非继承而来的方法:apply()和call()。;
call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性;
说明:
call()和apply()用来调用函数,并用指定对象(第一个参数)替换函数的this 值(改变this指向),同时用指定数组替换函数的参数。注:也可以不指定参数,此时只是单纯的调用函数,如:fun.call()
语法:
fun.call(thisobj,arg1,arg2) ;当后面参数个数确定时用call,参数之间用逗号连接
fun.apply(thisobj,[arg1,arg2]);当后面参数个数不确定时用apply,参数通过数组形式输入
call和apply的作用:
改变this的指向,第一个参数为你要传入的对象,传入后函数的this就指向了这个对象,后面的参数为你为函数传递的参数值
区别:
他们的区别在于接收参数的方式不同:
call():第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。在使用call()方法时,传递给函数的参数必须逐个列举出来。
apply():传递给函数的是参数数组
示例1:
示例2:
实例3:Max中获取最大值或最小值中的应用
实例4:apply/call在组合继承中应用
function Person(newId,newName){
this.id = newId;
this.name = newName;
}
Person.prototype.eat = function(){
console.log(this.name);
console.log("Person eat");
}
let p=new Person();
function Student(newId,newName,newScore){
//Person.call(this,newId,newName);
Person.apply(this,[newId,newName]);
this.score = newScore;
}
Student.prototype = new Person("11","222");
let student = new Student("007","老王",99);
console.log(student.id,student.name,student.score); //007 老王 99
student.eat(); //Person eat
复杂示例:
function log(){
var args=Array.prototype.slice.call(arguments);//将参数转为数组
//slice(start,end(非必须) )方法可从已有的数组中返回选定的元素。
//Javascript函数中的参数对象arguments是个对象,而不是数组。但它可以类似数组那样通过数字下表访问其中的元素,而且它也有length属性标识它的元素的个数。通常我们把它转换成数组用Array的slice函数,示例代码如下:function fn() { var arr = Array.prototype.slice.call(arguments,0);}
//所以Array.prototype.slice.call(arguments)就是将参数转为数组然后返回数组
console.log(args);//Array [ "hello", "world" ]
args.unshift('(gykj)');//unshift(a,b,c)向数组的开头添加至少一个元素
console.log(args);//Array [ "(gykj)", "hello", "world" ]
console.log.apply(console,args);//(gykj) hello world 这里的apply可以将数组元素作为字符参数输出
//由于参数个数不确定这里只能使用apply
}
log('hello','world')