this
JavaScript里面的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。
大致分为下面四种:
- 作为对象的方法调用
- 作为普通函数调用
- 构造器调用
- Function.prototype.call 或 Function.prototype.apply调用
1.作为对象的方法调用
var obj = {
name : 'zs',
getName : function(){
console.log(this === obj);//true
console.log(this.name);//zs
}
};
obj.getName();
2.作为普通函数调用
var name = 'zs';
var getName = function(){
return this.name;
}
console.log(getName());// return zs 这里的调用等同于window.getName() 所以this指向window对象
var age = 18;
var Obj = {
age : 22,
getAge : function(){
return this.age;
}
};
var getAggetAgee = Obj.getAge;
console.log(getAge());// return 18 这里也是在全局环境下面调用getAge,所以this也是指向window
//大致来说,this指向当前函数被调用的那个环境。上面两个方法都是在window下面被调用,所以this就指向了window
还有一种情况是,我们有时需要在回调函数里面使用this,但这个时候this往往不是我们预期的那个样子。这个时候,我们可以使用一个变量先保存this
var obj = {
name : 'zs',
getName : function(){
return this.name;
},
bindEvent : function(){
var that = this;
document.getElementById('dom').addEventListener('click',function(){
console.log(that.getName());
})
}
}
obj.bindEvent();//this.getName is not a function 这里的this指向了这个dom元素,所以找不到getName方法
//可以使用下面这种方法解决
bindEvent : function(){
var that = this;
document.getElementById('dom').addEventListener('click',function(){
console.log(that.getName());
})
}
3.构造器调用
JavaScript中没有类,但是可以通过构造器创建对象,同时也提供了new运算符,使的构造器看起来更像一个类。
在JS中,除了浏览器提供的一些内置函数,大部分JavaScript函数都可以当做构造器使用。构造器的外表和普通函数基本一模一样,区别主要在于被调用的方式。当使用new运算符调用函数时,这个函数就可以理解为构造函数(其实只是构造调用,和普通的函数还是一样的,只是调用的方式不一样),该函数总会返回一个对象,通常情况下,构造器里的this就指向返回的这个函数
var MyFunc = function(){
this.name = 'zs';
}
var func = new MyFunc();
console.log(func.name);//return zs
需要注意:如果使用new调用构造函数时,构造函数主动返回了一个object类型的对象,那么此次的运算结果最终会返回这个对象,而不是我们之前期待的this
var MyFunc = function(){
this.name = 'zs';
return {
name : 'ls'
}
}
var func = new MyFunc();
console.log(func.name);//return ls
如果构造器不显示的返回任何数据,或者是返回一个非对象类型的数据,就不会造成上面的问题(例如:上面那里如果是
return '123'
,是不会造成问题的)
4.Function.prototype.call和Function.prototype.apply调用
和普通的函数调用相比,call和apply可以动态的改变传入的this,他们的区别主要在接受的参数格式上
如果传入的第一个参数为null,函数体内的this会指向默认的宿主对象,浏览器里面是window
call(this,arg1,arg2...)
apply(this,[arg1,arg2])
var obj = {
name : 'zs',
getName : function(){
return this.name;
}
};
var anotherObj = {
name : 'ls'
};
console.log(obj.getName());//return zs
console.log(obj.getName.call(anotherObj));// return ls
Math.max.apply(null,[1,2,3,4]);//4