在JavaScript中,你的代碼將總是有着某種形式的上下文(代碼在其內部工作的 對象)。這也是其它面向對象語言所共有的功能,但它們都不如JavaScript處理得這樣極端。上下文是通過變量this工作。變量this總是引用代 碼當前所在的那個對象。記住全局對象實際上是window對象的屬性。這意味着即使是在全局上下文里,this 變量仍然引用一個對象。上下文可以成為一個強大的工具,是面向對象代碼不可或缺的一環。程序1展示了一些關於上下文的簡單例子。
程序1. 在上下文中使用函數然后將其上下文切換到另一個變量的例子

1 var obj = {
2 yes: function (){
3 // this == obj
4 this .val = true ;
5 },
6 no: function (){
7 this .val = false ;
8 }
9 };
10 // 我們看到,obj對象沒有"val"的屬性
11 alert( obj.val == null );
12 // 我們運行yes函數,它將改變附着在obj 對象的val屬性
13 obj.yes();
14 alert( obj.val == true );
15 // 然而,我們現在讓window.no指向obj.no方法,並運行之
16 window.no = obj.no;
17 window.no();
18 // 這導致obj對象保持不變(上下文則切換到了window對象),
19 alert( obj.val == true );
20 // 而window的val屬性被更新
21 alert( window.val == false );
2 yes: function (){
3 // this == obj
4 this .val = true ;
5 },
6 no: function (){
7 this .val = false ;
8 }
9 };
10 // 我們看到,obj對象沒有"val"的屬性
11 alert( obj.val == null );
12 // 我們運行yes函數,它將改變附着在obj 對象的val屬性
13 obj.yes();
14 alert( obj.val == true );
15 // 然而,我們現在讓window.no指向obj.no方法,並運行之
16 window.no = obj.no;
17 window.no();
18 // 這導致obj對象保持不變(上下文則切換到了window對象),
19 alert( obj.val == true );
20 // 而window的val屬性被更新
21 alert( window.val == false );
你 可能已經注意到,在程序1中,當我們切換obj.no方法的上下文到變量window時,笨重的代碼需要切換函數的上下文。幸運的 是,JavaScript 提供了兩種方法使這一過程變得更加易於理解和實現。程序2展示了恰能些目的的兩種不同方法,call和apply。
程序2. 改變函數上下文的示例
代碼
1 // 一個簡單的設置其上下文的顏色風格的函數
2 function changeColor( color ) {
3 this .style.color = color;
4 }
5 // 在window對象上調用這個函數將會出錯,因為window沒有style對象
6 changeColor( " white " );
7 // 得到一個id為"main"的對象
8 var main = document.getElementById( " main " );
9 // 用call方法改變它的顏色為黑
10 // call方法將第一個參數設置為上下文,
11 // 並其它所有參數傳遞給函數
12 changeColor.call( main, " black " );
13 // 一個設置body元素的顏色的函數
14 function setBodyColor() {
15 // apply方法設置上下文為body元素
16 // 第一個參數為設置的上下文,
17 // 第二個參數是一個被作為參數傳遞給函數的數組
18 // of arguments that gets passed to the function
19 changeColor.apply( document.body, arguments );
20 }
21 // 設置body元素的顏色為黑
22 setBodyColor( " black " );
2 function changeColor( color ) {
3 this .style.color = color;
4 }
5 // 在window對象上調用這個函數將會出錯,因為window沒有style對象
6 changeColor( " white " );
7 // 得到一個id為"main"的對象
8 var main = document.getElementById( " main " );
9 // 用call方法改變它的顏色為黑
10 // call方法將第一個參數設置為上下文,
11 // 並其它所有參數傳遞給函數
12 changeColor.call( main, " black " );
13 // 一個設置body元素的顏色的函數
14 function setBodyColor() {
15 // apply方法設置上下文為body元素
16 // 第一個參數為設置的上下文,
17 // 第二個參數是一個被作為參數傳遞給函數的數組
18 // of arguments that gets passed to the function
19 changeColor.apply( document.body, arguments );
20 }
21 // 設置body元素的顏色為黑
22 setBodyColor( " black " );