搜尋
首頁web前端js教程JavaScript程式碼編寫中各種各樣的坑和填坑方法_javascript技巧

坑」這個字,在此的意思是「陷阱」。由於JavaScript 「弱語言」的性質,使得其在使用過程中異常的寬鬆靈活,但也極為容易「中招」。這些坑往往隱藏著,所以必須擦亮雙眼,才能在學習與應用JS 的道路上走的一帆風順。

一、全域變數

JavaScript 透過函數管理作用域。在函數內部宣告的變數只在這個函數內部,函數外面不可用。另一方面,全域變數就是在任何函數外面聲明的或是未宣告直接簡單使用的。

“未聲明直接簡單使用”,指的是不用 var 關鍵字來聲明變數。這個我們已經很清楚,避免造成隱式產生全域變數的方法就是宣告變數盡量用 var 關鍵字。

可你以為用了 var 就 ok 了?來看看這個坑:


複製程式碼 程式碼如下:
function foo() {
    var a = b = 0;
    // 身體...
}

也許你期望得到的是兩個局部變量,但 b 卻是貨真價實的全域變數。 why? Because 賦值運算是自右往左的,所以這相當於:


複製程式碼 程式碼如下:

程式碼如下:

 
function foo() {
    var a = (b = 0);    // body...

}

所以 b 是全域變數。

填坑:變數聲明,最好一個個來,別搞批發~_~;

二、變量聲明

先來看坑:複製代碼

代碼如下:

 
myName = "global";

function foo() {
    alert(myName);
   alert(myName);
}

foo();

乍看上去,我們預期期望兩次alert 的結果分別為“global” 與“local”,但真實的結果是“undefined” 與“local”。 why? Because 變數在同一作用域(同一函數)中,宣告都是被提至作用域頂部先進行解析的。

所以以上程式碼片段的執行行為可能就像這樣:複製程式碼
程式碼如下:


function foo() {
    var myName;
    alert(myName); // "undefined"
    myName = "local";

    myName = "local";
🎜>}
用另一個坑來測試下你是否真的理解了預解析:複製代碼

代碼如下:

 
if (!("a" in window)) {
    var a = 1;
}

alert(a);
}alert(a);}alert(a);
a 變數的宣告被提前到了程式碼頂端,此時還未賦值。接下來進入 if 語句,判斷條件中 "a" in window 已成立(a 已被宣告為全域變數),所以判斷語句計算結果為 false,直接就跳出 if 語句了,所以 a 的值為 undefined。




複製程式碼


程式碼如下:

var a; // "undefined"

var a; // "undefined"

var a; // "un .log("a" in window); // true

if (!("a" in window)) {    var a = 1; // 不執行} alert(a); // "undefined"填坑:變數聲明,最好手動置於作用域頂部,對於無法當下賦值的變量,可採取先聲明後賦值的手法。

三、函數宣告


函數宣告也提前至作用域頂部,先於任何表達式和語句被解析和求值的


複製程式碼 程式碼如下: alert(typeof foo); // "function"
function foo() {    // body...}}可以比較一下:複製程式碼 程式碼如下:

alert(typeof foo); // "undefined"

var foo = function () {
    // body...
};















};明白了這個道理的你,是否還會踩到以下的坑呢? 複製程式碼

程式碼如下:
 
function test() {
 ");
}test();function test() {    alert("2");}
test( );


運行以上程式碼片段,看到的兩次彈跳窗顯示的都是 “2”,為什麼不是分別為 “1” 和 “2” 呢?很簡單,test 的宣告會先於 test() 被解析,由於後者覆寫前者,所以兩次執行的結果都是 “2”。

填坑:多數情況下,我用函數表達式來取代函數聲明,特別是在一些語句區塊中。

四、函數表達式

先看命名函數表達式,理所當然,就是它得有名字,例如:


複製程式碼 程式碼如下:var bar = function foo() {    // body...
};

要注意的是:函數名只對其函數內部可見。如以下坑:



複製程式碼

程式碼如下:

foo(); // 出錯:ReferenceError


填坑:盡量少用命名函數表達式(除了一些遞歸以及 debug 的用途),切勿將函數名稱使用於外部。


五、函數的自執行


對於函數表達式,可以透過後面加上 () 自執行,而且可在括號中傳遞參數,而函數宣告不可以。坑:




複製程式碼


程式碼如下:

 
// (1) 這只是分組運算符,不是函數呼叫!
// 所以這裡函數沒有執行,依舊是聲明
function foo(x) {
  alert(x);
}(1);

以下程式碼片段分別執行都彈跳視窗顯示“1”,因為在(1) 之前,都為函數表達式,所以這裡的()非分組操作符,而為運算符,表示呼叫執行。



複製程式碼

程式碼如下:// 標準的匿名函數表達式var bar>// 標準的匿名函數表達式var bar = function>var bar = function foo(x) {
  alert(x);}(1);// 前面的() 將function 宣告轉換為了表達式(function foo(x) {   alert(x);})(1);// 整個() 內為表達式(function foo(x) {  alert(x); }(1));// new 表達式new function foo(x) {  alert(x);}(1);// &&, ||, !, , -, ~ 等運算子(還有逗號),在函數表達式和函數宣告上消除歧義// 所以一旦解析器知道其中一個已經是表達式了,其它的也都預設為表達式了true && function foo(x) {  alert(x);}(1);填坑:這個坑的關鍵在於,弄清楚形形色色函數表達式的實質。 六、循環中的閉包以下演示的是一個常見的坑:複製代碼 程式碼如下:




   
文件 title><br><br>
   

點選下方的連結時,其序號


   
     href="#">連結#0
       
  • 連結#1

  •        
  • link #2

  •        
  • 連結#3

  •        
  • 連結#4

  •    


    複製程式碼程式碼如下:

    var links = 程式碼如下:


    var links = 程式碼如下:


    var links = 程式碼如下:

    var links = 程式碼如下:get. 0].getElementsByTagName("a");

    for (var i = 0, l = links.length; i     links[i].onclick = function (e ) {

            e.preventDefault();

           alert("您點選連結#" i);

       

    我們預期當點擊第 i 個鏈接時,得到這個序列索引 i 的值,實際上無論點擊哪個鏈接,得到的都是 i 在循環後的最終結果:”5”。

    解釋一下原因:當alert被呼叫時,對於循環內的匿名函數表達式,保留了對外部變數i的引用(閉包),此時循環已結束,i的值被修改為“5” 。 填坑:為了得到想要的結果,需要在每次循環中建立標記 i 的副本。以下示範正確的做法:
    複製程式碼


    程式碼如下:



      >


      -8">
        文件


       

    點選下方的連結時,顯示檔案數量其序列


       
           
  • < ;a href="#">#11 a>
  •        
  • 連結#2
  •        

  • 連結#3 a>
  •        
  • 連結#4
  •     html>



    複製程式碼


    程式碼如下:


    var links = 程式碼如下:
    var links = 程式碼如下:var links = 程式碼如下:var links = 程式碼如下.get 0].getElementsByTagName(“a”);for (var i = 0, l = links.length; i     links[i].onclick = (function (index) {         return function (e) {             (e.preventDefault();    })(i);}

    可以看到,(function () { ... })() 的形式,就是上文提到的函數的自執行,i 作為參數傳給了index,alert 再次執行時,它就擁有了對index 的引用,此時這個值是不會被循環改變的。當然,明白了其原理後,你也可以這樣寫:

    複製程式碼 程式碼如下:

    for (var i = 0, l = links.length ; i     (function (index) {
            links[i].onclick = function (e) {        }
        })(i);
    }


    It works too.
    陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

    JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

    JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

    JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

    Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

    Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

    Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

    選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

    Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

    Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

    JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

    javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

    JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

    JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

    Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

    選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

    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脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱門文章

    熱工具

    Atom編輯器mac版下載

    Atom編輯器mac版下載

    最受歡迎的的開源編輯器

    SublimeText3 英文版

    SublimeText3 英文版

    推薦:為Win版本,支援程式碼提示!

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    mPDF

    mPDF

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

    Dreamweaver Mac版

    Dreamweaver Mac版

    視覺化網頁開發工具