javascript中的this关键字到底是什么?
this是什么?
this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来感觉还是很拗口的,但是如果你把它拆分开来变成这三句话后就好理解一点了。
1.包含它的函数
2.作为方法被调用时
3.所属的对象
来看个简单的代码压压惊:
function showName(){
console.log(this); //window
}
showName();
参照上面的那三句话来解剖一下这个代码,首先this被showName函数包含了,其次showName()被调用了,最后是被谁调用了呢,我们知道全局定义的函数都是挂载到window对象上面的showName()相当于window.showName();所以this在这里就代表了window。如果还不明白的话我就简单粗暴点讲:
谁特么的调用了我,我就是谁的对象,谁特么的最后调用了我,我就是谁的对象。
继续看代码示例加深理解:
function testFun () {
var name="hello this!";
console.log(this.name);
}
testFun();
我们分析一下,因为test()函数是在全局中被window对象所调用的,那么this就理所当然的是指向window对象了,可是name变量是定义在testFun函数里面的,window对象中并没有定义name变量,当然也就不会打印出"hello this"这个字符串了。
那如果是这样呢?
var name = "hey";
function testFun() {
var name = "hello this!";
console.log(this.name);
}
testFun();
此时定义了一个全局变量name,即在window对象上定义了name,因此会打印出"hey"字符串来。
继续看个稍微复杂一点的:
var obj={
a:"哈哈哈",
b:function(){
var a="嘿嘿嘿";
console.log(this.a);
}
};
obj.b();
this被包含在函数b()中,但是因为是被对象obj所调用的,因此this属于对象obj,所以会打印出字符串"哈哈哈";
前面提到过 谁调用了我,我就属于谁,谁最后调用了我,我就属于谁。大家看下下面这个例子
var obj = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
};
obj.b.fn();
在这个例子中对象obj是在window上面定义的,所以obj.b.fn()=window.obj.b.fn(),那么大家会说this不是被window对象,或者被b调用了吗,请注意此时this最后是被fn锁调用的,所以this属于函数fn,因为在函数fn中并没有定义变量a,所以会打印出undefined;
大家可能还会经常遇到以下几种情况,但是只要牢记我说的那句话就不会有太大的问题。
<div class="box">
<button type="button" id="btn">我是一个按钮</button>
</div>
<script>
var btn=document.getElementById("btn");
btn.οnclick=function(){
console.log(this);//btn
}
</script>
this被btn调用所以this属于这个btn按钮对象,看效果图。
接下来我们思考一下this在构造函数中的指向
我们知道构造函数也是一个定义在window上面的函数,,所以构造函数里面的this属于window对象。看代码:
function People(){
var name1="aaa";
this.name2="bbb";
console.log(this);
}
People();
console.log(this.name1);
console.log(name2);
效果图:
因为this是指向window,而name1是定义在局部函数里面因此为undefined,this.name2="bbb";相当于是在window上面声明了一个变量。
上面讲的构造函数都是直接调用的,那如果构造函数是通过new实例化出来的this又会指向谁呢?
function People(){
var name1="aaa";
this.name2="bbb";
console.log(this);
}
var xiaoming=new People();
console.log(xiaoming .name1);
console.log(xiaoming.name2);
效果图:
我们发现this指向了People对象,name1此时为undefined,name2为"bb",这是问什么呢?
这是因为原本的构造函数是window对象的方法,如果不用new操作符而直接调用,那么构造函数的执行对象就 是window,即this指向了window。现在用new操作符后,this就指向了新生成的对象。