- 函数声明的情况
function add(){
var bj=20;
console.log(this);//window
console.log(this.bj);//10
console.log(bj);//20
console.log(this.bj+bj);//30
}
add();
window.add();</pre>
(1) 执行了add()之后,此时的this指向的是window对象,为什么呢?因为这时候add是全局函数,是通过window直接调用的。所以下面我专门写了个window.add()就是为了说明,全局函数的this都是指向的window。
(2) 就像alert()自带的警告弹窗一样,window.alert()执行之后也是一样的效果。所以只要是 window点 这种调用方式都可以省略掉,因此警告弹窗可以直接使用alert()。
- 函数表达式
var bj=10;
var zjj=function(){
var bj=30;
console.log(this);//window
console.log(this.bj);//10
console.log(bj);//30
console.log(this.bj+bj);//40
}
console.log(typeof zjj);//function
zjj();
window.zjj();
(1) 执行了zjj()之后,函数中的this也是指向window对象。原因和第一个是一样的,都是通过window这个对象直接调用。
- 函数作为对象的属性去调用
var bj=10;
var obj={
name:"八戒",
age:"500",
say:function(){
var bj=40;
console.log(this);//就是obj这个对象
console.log(this.bj);//undefined
console.log(this.name);//八戒
}
}
obj.say();
window.obj.say();
(1) 当obj.say()被执行的时候,此时的this指向的是 obj 这个对象,为什么呢?因为say函数是通过obj这个对象直接调用的。
(2) 那有人可能会问了,obj对象实际上也是通过window对象调用的,为什么this不指向window呢?我认为是因为say这个函数是通过 obj 对象直接调用的,而没有通过 window 对象直接调用,因此this不会指向window。看下面的例子就明白了。
3.1 函数作为对象的属性去调用
var bj=10;
var obj={
name:"八戒",
age:500,
say:function(){
console.log(this);//是obj这个对象
console.log(this.bj);//undefined
console.log(this.name)//八戒
},
action:{
name:"悟空",
age:1000,
say:function(){
console.log(this);//是action这个对象
console.log(this.bj);//undefined
console.log(this.name)//悟空
}
}
}
obj.say();
obj.action.say();
window.obj.action.say();
(1) obj.say()执行之后,此时这个函数里的this指向的是obj对象,原因是因为say函数是通过obj直接调用
的。
(2) obj.action.say()执行之后,此时这个函数里的this指向的是action对象,原因是因为say函数是通过action对象直接调用的。并没有通过obj直接调用。也没有通过 window 直接调用,所以此时action对象中say函数里的的this指向并不会是obj或者window。
3.2 函数作为对象的属性去调用
var bj=10;
var obj={
name:"八戒",
age:500,
say:function(){
console.log(this);//就是obj这个对象
console.log(this.bj);//undefined
console.log(this.name)//八戒
function wk(){
console.log(this);//window
console.log(this.bj);//10
console.log(this.name);//这里显示的是为空
}
wk();
},
}
obj.say();
(1) 这种情况下,say函数里的this指针还是指向的obj,原因是因为say函数是通过obj直接调用。
(2) 但是这时候wk函数中的this就是指向的是window了。为什么呢?因为 wk()函数在 say()函数中,是属于普通函数调用,但是并没有通过say或者obj直接调用,只是自执行,这个时候,wk就是一个全局函数,因此该函数的this指向的就是window。
(3) 那为什么this.name是显示的为空呢?因为 window 对象中本身就有一个 name 值,并不是某处添加的,如果把name换成age,得到的就是undefined了。
(4) 那怎样让wk()函数中的this指向obj呢。一种方式就是在say函数中把say()函数的this用变量保存起来,即 var that=this; 然后wk()函数使用that就能达到指向obj的目的了。另外的方式是通过apply或者call来改变。
(5) 那wk()在这里能不能写成window.wk()呢?这样是不行的,会报错,window.wk is not a function。为什么不行呢,this不是指向window吗,为什么widow对象里灭有wk()这个函数。。这个嘛,我也不知道,先留个坑,后面再来填 ×××
3.3 函数作为对象的属性去调用
var bj=10;
var obj={
name:"八戒",
age:"500",
say:function(){
var bj=40;
console.log(this);//window
console.log(this.bj);//10
console.log(this.name);//这里没有输出内容
}
}
var elseObj=obj.say;
elseObj();
执行了elseObj()函数之后,为什么say函数中的this却指向了window呢?首先要理解这句话:谁直接调用产生这个this指针的函数,this就指向谁。当obj.say赋值给elseObj的时候,elseObj只是一个函数,而并没有执行,因此this指针的指向并不明确,这个时候执行到 var elseObj=obj.say的 时候,整程序相当于:函数表达式。