解析器在调用函数时每次都会向函数内部传递进一个隐含的参数
- 这个隐含的参数就是 this ,this 指向的是一个对象,
- 这个对象我们称为函数执行的上下文对象,
this 的由来
javascript 允许在函数体内,引用当前环境的其它变量var fun = function(){
console.log(x);
}
上面代码使用变量x,而变量x由当前的运行环境提供。
那么问题来了,函数可以在不同的运行环境下执行,所以需要一种机制,可以在函数体内内部获取当前的运行环境(context),所以this就出现了,它的作用就是在函数体内部,指代当前的运行环境。
根据函数的调用方式的不同,this 会指向不同的对象
- this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,
以函数的形式调用时,this 永远都是 全局对象 window
以上代码中,getAge方法在全局window下调用,所以getAge方法内的this指向的是window。为了更好的验证这一点,咱们再来对以上代码修改如下://定义一个全局变量age
var age=18;
//声明一个全局函数getAge
function getAge(){
return this.age;
}
//因为是全局环境内调用的getAget函数所以指向的对象为window
console.log(getAge());//18
//你也可以这样写
console.log(window.getAge());//18
以上代码中声明了一个全局函数getAge。由于该函数在全局环境(window)下调用,所以this为window。然后通过this.age为window对象增加一个age属性。所以在调用完该函数后进行console.log(window.age)输出的结果为81。//声明一个全局函数getAge
function getAge(){
//由于该函数在全局环境(window)下调用,所以this为window
this.age=81;//为this指向的window对象添加属性age
}
getAge();//全局调用函数getAge()
console.log(age);//81
//也可以这样输出
console.log(window.age);//81
以方法的形式调用时,this 就是调用方法的那个对象
var name = "哈哈";
var obj = {
name:"嘿嘿",
getName:function(){
return this.name;
}
}
console.log(obj.getName()); // 嘿嘿
var obj={
//obj属性age
age:12,
//obj方法getAge
getAge:function(){
return this.age;
}
}
//全局属性age
var age=13;
//全局方法getAge
function getAge(){
return this.age;
}
//在全局环境下,this代表window,所以下面可以理解为window对象下调用全局getAge
console.log(this.getAge());//13
在全局环境下,this代表的是window。所以调取的方法为全局方法getAge。又因为getAge是在window下调用的,所以内部this指向的是window对象。最终输出结果为13。
接下来看种丢失掉this的情况,换言之,this的指向发生改变。我们先来看下面的代码
var obj={
//obj属性age
age:12,
//obj方法getAge
getAge:function(){
return this.age;
}
}
//全局属性age
var age=13;
//全局方法getAge
function getAge(){
return this.age;
}
//在obj对象下调用getAge(),this代表的是obj
console.log(obj.getAge());//12
//将obj下的函数getAge赋值给fn。
var fn=obj.getAge;
//在全局环境(window) 下调用fn,this代表的是window
console.log(fn());//13
当调用obj.getAge时,getAge方法是作为obj对象的属性来调用的。输出结果为12。当将obj.getAge赋值给一个变量fn时,因为fn的调用是在全局环境下调用的,所以this指向的是window,输出结果为13。
将代码汇总如下,认真看看:
var obj={
//obj属性age
age:12,
//obj方法getAge
getAge:function(){
return this.age;
}
}
//全局属性age
var age=13;
//全局方法getAge
function getAge(){
return this.age;
}
//在obj对象下调用getAge(),this代表的是obj
console.log(obj.getAge());//12
//在全局环境下,this代表window,所以下面可以理解为window对象下调用全局getAge
console.log(this.getAge());//13
//将obj下的函数getAge赋值给fn。
var fn=obj.getAge;
//在全局环境(window) 下调用fn,this代表的是window
console.log(fn());//13