定义
apply()方法:
Function.apply(obj,args)
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)
call()方法:
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
相同点
作用是一样的,call 和 apply 都是为了改变函数体内部 this 的指向,也就是把Function(即this)绑定到obj,这时候obj具备了Function的属性和方法,说白一点就是obj继承了Function的属性和方法。
不同点
相信大家也已经发现了,他们唯一区别就是接受参数的方式不太一样,apply接受的是数组参数,call接受的是连续参数。
方法使用1
function mul(a,b){
return this+(a*b);
}
//接着我们在控制台上打印出
console.log(mul.call(null,2,3));
console.log(mul.call('s',2,3));
console.log(mul.call(3,2,3));
console.log(mul.apply(null,[2,5]));
console.log(mul.apply(2,[2,5]));
结果
[object Window]6
s6
9
[object Window]10
12
方法使用2
学js的都知道 Math.max()方法,比如有三个参数2,3,4那么我们要找出最大值可以这么写 Math.max(2,3,4) 那要是有 100 个或更多参数呢?这时候就可以结合 apply 和数组轻松实现了。
var arr=[2,3,4,5,6,7,8,9,10,23,45,66,22,11];
console.log(Math.max.apply(null,arr));
方法使用3-----对象继承
function Person(name,age) {
this.name=name;
this.age=age;
}
var Student=function(name,age,gender) {
Person.call(this,name,age);//this继承了person的属性和方法
this.gender=gender;
}
var student=new Student("王刚", 20, "男");
alert("姓名:"+student.name+"\n"+"年龄:"+student.age+"\n"+"性别:"+student.gender);
输出
姓名:王刚
年龄:20
性别:男
这样用call就实现了继承(用apply也类似)
原理简单解析
我们来看下面示例:
function fn1() {
console.log(1);
}
function fn2() {
console.log(2);
}
fn1.call(fn2);//执行call方法,里面执行fn1,并且让f1函数中的this变成fn2,输出的结果是1
fn1.call.call(fn2);//执行第二个call方法,在这个call方法里面,执行fn1.call,让fn1.call这个方法中的this变成fn2,输出的结果是2
fn1.call(fn2)的结果相信大部分童鞋都明白,fn1.call.call(fn2)的结果似乎出乎你我的意料之外,这是为什么呢?下面就给大家分析下各自产生的结果流程:
fn1.call(fn2)
Function.prototype.call(fn1);//执行call方法,在call方法里面让 Function.prototype执行,并且把Function.prototype中的this改变成fn1
Function.prototype对应的不是一个对象而是一个函数(Empty)
fn1.call.call(fn2)
//第一个call执行:
Function.prototype.call.call(fn2);//执行call方法,在call里面让Function.prototype.call执行,
并且让这个call方法中的this是fn2,其实就是让fn2执行
和我们的fn1.call.call(fn2)一样 Function.prototype.call==fn1.call
//第二个call执行:
fn1.call(); -->fn1.call这个方法中的this变成fn2
fn1.call获取的是我们Function这个原型上的call方法,也就是让Function原型上的call方法执行,让里面的this变成fn2
[参考下代码]
this(); -->fn2();
fn.call 为啥函数可以调用call这个方法?
Function js中所有的函数数据类型对应的基类 call和apply就是定义在Function这个基类的原型上的,而每一个函数都是Function这个基类的一个实例,所有所有的函数都可以使用call和apply方法
Function.prototype.call = function () {
call这个方法中的this就是我们的fn1
1、让fn1执行
this();
2、把fn1中的this改变成我们第一个参数传的值
把this函数中的[this]改变成arguments[0]
}