使用语法
- 函数名字.apply(对象,[参数1,参数2,…])
- 方法名字.apply(对象,[参数1,参数2,…])
- call的使用语法
- 函数名字.call(对象,参数1,参数2,…);
- 方法名字.call(对象,参数1,参数2,…);
作用:改变this的指向
不同的地方:参数传递的方式是不一样的
要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用apply或者是call的方法改变this的指向
小栗子:
构造函数,添加原型方法
function Person(name,sex) {
this.name=name;
this.sex=sex;
};
Person.prototype.sayHi=function (x,y) {
console.log("你好啊:"+this.name)
return x+y;
};
实例化对象,调用方法
var per=new Person("小明","男");
per.sayHi();//你好啊:小明
这里无需过多阐述,正常输出
下面再来一个构造函数和实例化对象:
function Student(name) {
this.name=name;
};
var stu=Student("小红");
现在对于这个stu这个对象并没有定义方法现在要利用apply和call来调用Person的的原型方法sayHi
//改变了this的指向
per.sayHi.apply(stu,[10,20]);//你好啊:小红
per.sayHi.call(stu,10,20);//你好啊:小红
我们可以看到apply和call改变了this的指向让stu调用到了Person的方法
但是我们可以看到在Person的原型方法sayHi我们还加了返回值,下面来接受一下返回值
如果有返回值的话,声明变量接收
var result1=per.sayHi.apply(stu,[10,20]);//30
var result2=per.sayHi.call(stu,30,20);//50
这个方法很实用也很简单易于理解,我们来深入看看他的原理吧
原理:
我将重新写演示代码方便阅读
//apply和call方法的使用
function f1(x,y) {
console.log((x+y)+"========"+this);
return "函数返回值";
};
var r1=f1.apply(null,[10,20]);//此时this是window
var r2=f1.call(null,10,20);//此时this是window
console.log(r1+"==="+r2);
var obj={
};
var r3=f1.apply(obj,[30,60]);//此时的this是obj
var r4=f1.call(obj,30,60);//此时的this是obj
console.log(r3+"==="+r4);
this的指向改变了,并且把它输出出来了,比较直观
function f1() {
console.log(this+":====>调用了");
}
//f1是函数,f1也是对象
console.dir(f1);
//对象调用方法,说明,该对象中有这个方法
f1.apply();
f1.call();
console.log(f1.__proto__==Function.prototype);
//所有的函数都是Function的实例对象
console.log(Function.prototype);//ƒ () { [native code] }
console.dir(Function);
//apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype中
我们可以看到改变指向的所调的方式实际上并不在他们自己的实例对象和构造函数中而是在Function的prototype中
总结:
使用apply和call可以改变this 的指向,从而调用我们想要调用的方法,而调用的对象本身是没有这个方法的,但是他有apply和this,apply和this都在Function中,实际上是从Function中调的方法