目錄
點選下方的連結時,其序號
點選下方的連結時,顯示檔案數量其序列
首頁 web前端 js教程 JavaScript程式碼編寫中各種各樣的坑和填坑方法_javascript技巧

JavaScript程式碼編寫中各種各樣的坑和填坑方法_javascript技巧

May 16, 2016 pm 04:45 PM
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

    熱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.能量晶體解釋及其做什麼(黃色晶體)
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.聊天命令以及如何使用它們
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

    如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

    WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

    WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

    如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

    如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

    如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

    如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

    JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

    JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

    簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

    JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

    javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

    用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

    JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

    JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

    See all articles