1.普通函数
普通函数的this,是与它的调用环境相关的。我们不妨举个例子来看看。
function globleTest(){
console.log(this); //window
}
globleTest();
这个时候函数的this是指向window的,那我们再来看一个例子
var test ={
a:1,
b:function(){
console.log(this); //指向对象test
console.log(this.a); //1
}
}
test.b();
这个时候函数的this是指向调用它的对象test,这与我们把b从test中解构出来,然后再执行结果是一样的。
需要注意的是对象下的方法不一定总是指向对象,比如:
var obj = {
name:'obj'
,fn:function(){
console.log(this);
}
}
obj.fn(); //this->obj
var f = obj.fn; //把obj.fn的地址给了小f
f(); //this->window
那么假如我们使用用const来申明呢,结果会不会发生变化呢?如果没有发生变化,原理是否是一样的呢?
const {b} = test;
b(); //Object
console.log(window);
运行这段代码,你会发现,打印出的仍然是一个对象,但是这个时候打印出window,你会惊讶的发现window里面其实是没有b函数的,它其实存在于Script的当中,这个变量并不能通过console.log打印出来,我们可以通过调试的方式来看到它的值
匿名函数它也是一个普通函数
2.箭头函数
普通函数的情况我们就看到这里吧,接下来我们来看一看箭头函数中的this指向。
箭头函数中的this指向,其实是继承父执行上下文中this指向。如果比较难理解,那我们就通过例子来理解一下吧。
var a1 = {
a1:1,
b:()=>{
console.log(this.a);
}
}
a1.b(); //Object
我们可以看到打印结果是一个Object,原因在于 对象它是没有执行上下文的,所以箭头函数里面的this是没有绑定obj的,应该是绑定到了window上
当遇到匿名函数时
var a2 = {
a2:1,
b:function(){
return ()=>{
console.log(this.a2);
}
}
};
a2.b()(); //1
此时箭头函数的this就指向匿名函数的this,前面我们说了匿名函数是一个普通函数,它的this应该是指向调用者的
测试一下你自己
var a3 = function(){
var a3 =123;
var b=()=>{
console.log(this.a3);
}
var c=function(){
console.log(this.a3);
}
b();
c();
}
a3();
结果应该是两个都是输出function,首先我们来看b,b是一个箭头函数,它的this指向a3这个function的指向,这个function是一个普通函数,所以它的指向是window
再来看一下c,c本身就是一个普通函数,它的this指向的调用时候的环境,即为window
var obj3 = {
num:4,
fn:function(){
console.log(this); //Object
var f = function(){
console.log(this); //window
setTimeout(()=>{
console.log(this); //window
})
}
f();
}
}
obj3.fn();
第一个输出应该是Object,因为fn是通过obj3调用的,但是第二个console.log输出的应该是window,因为f是在全局环境当中执行的,而最后一个console.log输出的也是window,因为箭头函数中的this指向父执行上下文中的this指向,指向的是f,因为f是在全局环境下执行的,所以f中的this指向window
那么当setTimeout中的函数不是一个箭头函数了,会出现什么样的情况呢?
var obj4 = {
num:4,
fn:function(){
console.log(this); //Object
var f = ()=>{
setTimeout(function(){
console.log(this); //window
})
}
f();
}
}
obj4.fn();