搜尋
首頁web前端js教程深入理解Javascript中this的作用域_javascript技巧

大家在使用Javascript的時候常常被this這傢伙搞得暈頭轉向的。對大多數有OOP開發經驗的開發人員來說this是當前作用域中引用普通元素的標識符,但是在Javascript中它卻顯得古靈精怪的,因為它不是固定不變的,而是隨著它的執行環境的改變而改變。在Javascript中this總是指向呼叫它所在方法的物件。

舉一個簡單的例子:

複製程式碼 程式碼如下:

function test(){
alert(this);
}
var obj=function(){
var name='testObj';
}
obj.objTest=test;
test();
obj.objTest();

把這段程式碼放到HTML中執行這個頁面,你會看到先提示一個警告[object window],然後第二個警告。

複製程式碼 程式碼如下:

var obj=function(){
var name='testObj';
}

我們先定義了一個test()方法,並在方法內部呼叫alert()方法將this顯示出來,然後定義了一個obj函數對象,並給它加了一個私有的字段name,同時給它加了一個靜態的方法objTest(),而這個函數則直接指向test()函數。

分別呼叫test()和obj.objTest()方法,第一次警告框提示的是Window對象,而第二次提示的是我們定義的obj這個函數的程式碼。這說明了test函數在兩次執行的時候this的值是不同的!

這就說明了當呼叫函數的物件不同的時候,其內部的this關鍵字指涉的物件是不同的。這裡需要值得注意的是Javascript是基於物件的語言,當我們的變數或函數定義在<script></script>標籤的根下的時候其實相當於給window物件加了對應的屬性或方法,所以當我們利用function test(){}程式碼定義一個函數的時候,其實相當於為window物件增加了一個新的函數,也就是window.test()函數。

我們可以做個實驗:

複製程式碼 程式碼如下:

function test(){
alert(this);
}
alert(test===window.test);

警告框提示的將是true,這表示當我們在呼叫test()這個函數時相當於呼叫的是window.test()。所以當我們呼叫test()函數的時候呼叫這個函數的對像其實是window對象,this指涉的是window對象,所以我們在alert(this)的時候彈出的警告視窗內容是[object Window]。我們將obj.objTest=test相當於把obj.objTest()指向test(),所以當我們呼叫obj.objTest()函數時相當於在obj呼叫了test()這個函數,所以現在this指代的是obj對象,提示的就是obj這個Function也就是我們看到的程式碼。

說到這應該也解釋的差不多了,可能上面的例子太抽象,想像不出來它能在什麼情況下用到,那我們現在就假設一個需求,做一個貼近實用一點的例子。

假設我們現在頁面中的所有超連結在點擊之後顏色要改為紅色,用Javascript實作。大體的想法應該是取得頁面中所有的標籤,然後遍歷所有的標籤,給每一個註冊一個click事件,事件觸發後我們將它的color值設為red。

範例程式碼如下:

複製程式碼 程式碼如下:

//改顏色
function changeColor(){
this.style.color='#f00';
}
//初始化,給所有 a 標籤註冊事件
function init(){
var customLinks=document.getElementsByTagName('a');
for(i in customLinks){
//你也可以使用事件偵聽器方式來註冊事件
//由於要相容IE,FF等瀏覽器可能需要更多程式碼,您可以自行編寫
customLinks[i].onclick=changeColor;
}
}
window.onload=init;

將這段程式碼加入HTML文件中,並在文件中加入一些超鏈接,當超連結點擊後顏色會變成紅色,這裡我們定義的changeColor()函數中this關鍵字在點擊超連結觸發函數的時候它指涉的是當前這個超連結。而如果你直接呼叫changeColor()函數瀏覽器會報錯,提示Error: ‘this.style' is null or not an object或undefined之類的錯誤。

不知道說到這能不能讓正在看文章的你對Javascript中的this關鍵字有了一些自己的了解呢?還是你已經不耐煩了? (:P)

其實要想真正對這個問題有更深入的理解那麼必須對Javascript的作用域和作用域鏈有深入的理解。

作用域,顧名思義就是指某一屬性或方法具有存取權限的程式碼空間,簡單的說也就是這個變數或方法它在程式碼中的適用範圍。在大多數的OOP中主要有public,private,protect三種作用域,對著三種作用域在這裡就不詳細解釋了,如果有OOP的經驗應該都有深入的了解。這裡我要說的是這三種作用域類型對Javascript來說幾乎是毫無意義的,因為Javascript中只有一種公共作用域,在Javascript中作用域是在函數中進行維護的。舉例:

複製程式碼 程式碼如下:

var test1='globle variable';
function example(){
var test2='example variable';
alert(test1);
alert(test2);
}
example();
alert(test1);
alert(test2);

根據我們前面解釋的,這裡的test1變數相當於window的一個屬性,所以它會在整個window作用域內起作用,而test2則在example()函數的內部聲明,所以它的作用域也就維持在example()方法的內部,如果在函數的外部呼叫test2瀏覽器會提示出錯。而在example()內部呼叫test1則沒問題。

根據這個我們再舉一個例子:

複製程式碼 程式碼如下:

var test='globle variable';
function example(){
var test='example variable';
}
example();
alert(test);

這個範例運行會是什麼結果呢?對,警告框會提示“globle variable”,因為example()函數內部的test變數其作用域只維持在內部,不會影響外部的test變數。如果我們將example()內部test變數的var關鍵字去掉呢?你可以自己試試看。

說到這就有牽扯出另外一個概念,那就是作用域鏈的概念。作用域鏈就是可以確定變數值的路徑。由上面一個例子可以看出,var關鍵字是用來維護作用域鏈的,如果變數使用了var關鍵字聲明那麼他就可以看作為作用域鏈的終點。同樣函數的形參的定義也會起到類似的作用。

說到這你對this這個精靈古怪的傢伙有了比較清晰的認識了吧?根據它簡單的一個詮釋,this總是指向調用它所在函數的對象,根據作用域和作用域鏈,我們會很清晰的確定this的真面目。臨末再來一個開始那個例子的簡單變化:

複製程式碼 程式碼如下:

function test(){
alert(this);
}
var obj=function(){
var name='testObj';
}
obj.objTest=test;
obj.objTest2=function(){
test();
}
test();
obj.objTest();
obj.objTest2();

你猜會提示什麼內容呢?你可以運行一下試試(:P);

既然this是根據呼叫其所在函數的物件的改變而改變的,那我們可不可以強制改變它的呼叫物件呢?答案是肯定的,以後的文章會介紹一下這部分內容,以及Javascript中不同類型的資料成員的實作方式,閉包等概念。

本人在學習過程中的一些經驗和心得體會,寫出來一是與大家分享另外也能檢視自己的不足,如寫的有問題還請批評指教,甚為感謝!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?Apr 04, 2025 pm 09:21 PM

在JavaScript中如何獲取原型鏈上函數的參數在JavaScript編程中,理解和操作原型鏈上的函數參數是常見且重要的任�...

微信小程序webview中Vue.js動態style位移失效是什麼原因?微信小程序webview中Vue.js動態style位移失效是什麼原因?Apr 04, 2025 pm 09:18 PM

在微信小程序web-view中使用Vue.js動態style位移失效的原因分析在使用Vue.js...

在Tampermonkey中如何實現對多個鏈接的並發GET請求並依次判斷返回結果?在Tampermonkey中如何實現對多個鏈接的並發GET請求並依次判斷返回結果?Apr 04, 2025 pm 09:15 PM

在Tampermonkey中如何對多個鏈接進行並發GET請求並依次判斷返回結果?在Tampermonkey腳本中,我們經常需要對多個鏈...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。