函數的上下文就是函數裏面的this是誰
規律1:函數用圓括號調用,函數的上下文是window對象
比如小題目:
function fun(){
var a = 888;
alert(this.a); //實際上訪問的是window.a
}
var a = 666;
fun(); //彈出666
函數function fun(){}的上下文是什麽!不要看它怎麽定義,要看它怎麽調用!!此時是fun()函數名加上圓括號直接調用,此時上下文就是window對象!
而我們知道:所有的全局變量都是window對象的屬性,(註意:函數裏面的局部變量,不是window的屬性,不是任何東西的屬性,它就是一個變量!!) 程序彈出666.
規律2:函數如果作為一個對象的方法,對象打點調用,函數的上下文就是這個對象
比如下面的例子,我們把fun函數定義出來了,然後又把這個函數綁定給了obj對象的c屬性:
function fun(){
alert(this.a); //相當於彈出obj.a
}
//對象
var obj = {
"a" : 10,
"b" : 20,
//給這個對象增加一個方法,值就是fun函數
"c" : fun
}
//我們要看清楚函數執行的時候,是怎麽執行的!!
//現在不是圓括號直接執行!!而是一個對象打點調用這個函數執行,所以函數的上下文是obj對象!!!
obj.c(); //彈出10
調用的時候,是
對象.函數()
此時根據規律,函數裏面的this是這個對象。所以能夠彈出10。
規律3:函數是事件處理函數,函數的上下文就是觸發這個事件的對象
下面我們定義了一個fun,然後把這個fun當做了3個DOM元素的事件處理函數:
//函數
function fun(){
this.style.background = "red";
}
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
// 把同一個函數綁定給不同的對象
// this就是點擊誰就是誰
box1.onclick = fun;
box2.onclick = fun;
box3.onclick = fun;
函數不會執行,直到用戶點擊了某一個div標簽。此時點擊誰,this就是誰。
規律4:定時器調用函數,上下文是window對象
//函數
function fun(){
alert(this.a);
}
var a = 888;
setInterval(fun,1000);
函數fun被定時器調用,此時函數的上下文就是window對象。每秒鐘能彈出888.
做一個小例子吧,點擊一個盒子,2秒鐘之後變紅:
小明同學寫的程序是錯誤的:
var box1 = document.getElementById("box1");
box1.onclick = function(){
setTimeout(function(){
this.style.background = "red";
},2000);
}
這是因為我標藍色的函數的最終調用者是定時器!所以函數的上下文是window對象。window對象沒有背景顏色屬性。
怎麽辦?備份this!備份上下文!
在定時器外面的事件處理函數中,this就是box1這個元素,此時我們可以備份上下文。把this存為局部變量self,後面的程序就用self指代box1。還可以用_this、that等等,我們一律使用self。
var box1 = document.getElementById("box1");
box1.onclick = function(){
var self = this;
setTimeout(function(){
self.style.background = "red";
},2000);
}
規律5:數組中存放的函數,被數組索引之後加圓括號調用,this就是這個數組
比如:
function fun(){
alert(this === arr); //true
alert(this.length); //3,因為數組的長度是3
}
var arr = [fun,"東風","五條"];
arr[0]();
一定要敏感:
arr[0]();
此時這個函數是從數組中枚舉出來然後加圓括號執行的,所以最終調用者可以認為是這個數組,上下文就是這個數組。
函數的上下文就是函數裏面的this是誰