初學JavaScript經常被this繞暈,所以我總結一下JavaScript中的this。
首先聲明本文討論的是非嚴格模式下的this,因為嚴格模式下this進入運行環(huán)境前是禁止指向全局變量的,默認undefined。(什么是嚴格模式?阮一峰大神博客的傳送門)
既然說到這兒了,順便摘錄上面博客的一個例子(因為很像面試題)
function f(){
return !this;
}
// 返回false,因為"this"指向全局對象obj window,"!this"就是false
function f(){
"use strict";
return !this;
}
// 返回true,因為嚴格模式下,this的值為undefined,所以"!this"為true。
全局上下文
最簡單的例子
console.log(window===this)//true,瀏覽器里全局對象就是window(假設是在瀏覽器環(huán)境下)
console.log(document.this===document);//true
注意,這種情況嚴格模式和非嚴格模式是一樣的
函數上下文
直接調用
this指向全局變量window
function f0(){
f1(){
console.log(this);//指向全局變量window
}
f1();
}
f0();
對象方法中的this
這種情況下this會被綁定到調用它的對象
var obj={
p:function(){
console.log(this);//obj
}
}
obj.p();
原型鏈中的this
this還是指向調用它的對象,只是方法可以從原型鏈上繼承
var o={
f:function(){
console.log(this.a);
}
};
var p=Object.create(o);
p.a=1;
p.f();//p從原型鏈上繼承f方法,輸出1,this指向調用它的p
構造函數中的this
this與即將被創(chuàng)建的新對象綁定
function Car(){
this.color='red';
this.maxspeed=100;
}
var car1=new Car();
console.log(car1.color);//'red'
console.log(car1.maxspeed);//100
.call()、.apply()
function isAdult(name,age){
if(age<18){
console.log(name+" is not an adult");
}else {
console.log(name+" is an adult");
}
}
function Person(name,age){
this.name=name;
this.age=age;
isAdult.call(this,name,age);
/*isAdult.apply(this,arguments); 這里如果用apply也是一樣的*/
}
var user1=new Person('Tom',10),//Tom is not an adult
user2=new Person('Wang',22);//Wang is an adult
.call()、.apply()函數本身的作用就是將函數運行上下文環(huán)境綁定到傳入的第一個參數所指的環(huán)境上,上例就是使用了這種方法
DOM事件中的this
btn.on('click', function(){
console.log(this)//this指向btn
}
DOM事件的this指向觸發(fā)事件的元素
這里再舉一個例子,如果不想要this指向btn怎么辦?
var p={
var self=this;
bind:btn.on('click', function(){
console.log(this)// 繞開this,self指向p
}
}
setTimeout()、setInterval()中的this
setTimeout()、setInterval()中的this指向全局對象
document.addEventListener('click', function(event){
console.log(this);//this指綁定事件的dom節(jié)點
setTimeout(function(){
console.log(this);//全局對象,瀏覽器里就是window
}, 200);
}, false);
可以對比兩個this,輸出結果不一樣
內聯事件處理函數中的 this
當代碼被內聯處理函數調用時,它的this指向監(jiān)聽器所在的DOM元素:
<button onclick="alert(this.tagName.toLowerCase());">
Show this
</button>
注意只有外層代碼中的this是這樣的,下面的this按照前面所講函數上下文情況中的直接調用,指向全局對象window:
<button onclick="alert((function(){return this}}()));">
Show inner this
</button>