重点:在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。
情况1:构造函数
所谓构造函数就是用来new对象的函数。其实严格来说,所有的函数都可以new一个对象,但是有些函数的定义是为了new一个对象,而有些函数则不是。另外注意,构造函数的函数名第一个字母大写(规则约定)。例如:Object、Array、Function等。
function Foo(){
this.name="小雪";
this.year=1993;
console.log(this);//Foo{name:'小雪',year:1993}
}
var f1=new Foo()
console.log(f1.name);//小雪
console.log(f1.year);//1993
以上代码中,如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。
注意,以上仅限new Foo()的情况,即Foo函数作为构造函数的情况。如果直接调用Foo函数,而不是new Foo(),情况就大不一样了。
function Foo(){
this.name="小雪";
this.year=1993;
console.log(this);//Window {frames: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
}
Foo();
情况2:函数作为对象的一个属性
如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this指向该对象。
var obj = {
x: 10,
fn: function () {
console.log(this); //Object{x:10,fn:function}
console.log(this.x); //10
}
}
obj.fn()
fn不仅作为一个对象的一个属性,而且的确是作为对象的一个属性被调用。结果this就是obj对象。
注意,如果fn函数不作为obj的一个属性被调用,会是什么结果呢?
var obj = {
x: 10,
fn: function () {
console.log(this); //Window
console.log(this.x); //undefined
}
}
var fn1=obj.fn;
fn1();
情况3:函数用call或者apply调用
当一个函数被call和apply调用时,this的值就取传入的对象的值。
var obj = {
x: 10
}
var fn=function () {
console.log(this); //Object{x:10}
console.log(this.x); //10
}
fn.call(obj);
情况4:全局 & 调用普通函数
在全局环境下,this永远是window
var x=10;
var fn=function(){
console.log(this); //Window
console.log(this.x);//10
}
fn();
特别注意
var obj={
x:10,
fn:function(){
function fn1(){
console.log(this); //Window
console.log(this.x); //undefined
}
fn1();
}
}
obj.fn();
函数fn1虽然是在obj.fn内部定义的,但是它仍然是一个普通的函数,this仍然指向window。
。。。。。总结成一句话就是:this总是指向调用该函数的对象。