1、js的this总是指向对象,具体指向哪个对象是在运行时给予函数的执行环境动态绑定的。
this指向大体分为4种:
- 作为对象的方法调用
- 作为普通函数调用
- 构造器调用
- call、appy调用
首先看一下下面的例子:
window.name="nikon";
var myObject={
name:'stven',
getName:function(){
return this.name;
}
}
var getName=myObject.getName;
var getThisName=myObject.getName();
alert(getName()); //nikon
alert(getThisName); //stven
两者的返回结果不同,而这样的不同也是平时容易混淆的地方。‘var getName=myObject.getName;’是作为普通函数调用,返回的this指向的全局的window.name;‘var getThisName=myObject.getName();’是作为对象的方法调用,this指向该对象。
有时我们会困扰,比如div节点的事件函数内部,有一个局部的callback方法,callback被作为普通函数调用,this指向全局,这样我们无法获取到该div节点,如果想要get到该节点,可以用一个变量保存这个div节点的引用:
document.getElementById("div1").onclick = function(){
var that = this;
var callback = function(){
alert(that.id);
}
callback();
}
2、apply和call的区别
二者作用是一模一样的,区别在于传入参数形式不用
apply接受两个参数,第一个参数是函数体内this对象的指向,第二个参数为一个带下标的集合,这个集合可以是数组也可以是类数组,apply把这个集合中的元素作为参数传递给被调用的函数:
var func=function(a,b,c){
alert([a,b,c]);
}
func.apply(null,[1,2,3]);
call传入的参数不固定,和apply一样的是第一个参数是函数体内this对象的指向,第二个参数开始,每个参数依次传入函数体内
var func=function(a,b,c){
alert([a,b,c]);
}
func.apply(null,1,2,3);
当调用一个函数时,js的解释器并不会计较形参和实参在数量、类型以及顺序上的区别,js的参数在内部就是用一个数组来表示的,从这个意义上讲,apply比call使用率更高。我们不用关心多少参数传入,只要用apply一股脑的传进去就行了。
3、call和apply的用途
3.1、改变this指向
var obj1={
name:'sevn'
}
var obj2={
name:'frank'
}
window.name='window';
var genName=function(){
alert(this.name);
}
getName.call(obj1); //sevn
getName.call(obj2); //frank
3.2 Function.prototype.bind,用于指定函数内部的this指向
var obj={
name:'sven'
}
var func=function(){
alert(this.name);
}.bind(obj);
func(); //sven