了回饋社區,codeburst 從他們公司的上千個項目中,整理了 JavaScript 出現次數最多的 10 個錯誤。如果能避免這些錯誤的話,那么你能成為一個更好的程序員。以下就是排名最高的 10 個 錯誤:?
這個錯誤大家應該經常碰到,當你在 Chrome 瀏覽器中,從一個 undefined 的對象上嘗試讀取一個屬性或者調用一個方法的時候,就會拋出這個錯誤:?
上述相同的錯誤,在 Safari 瀏覽器中給出的是不同的錯誤信息,在 Safari 瀏覽器上實驗可以得到這個結果。
在 Safari 瀏覽器上,從一個 null 對象上讀取屬性或者調用方法的時候,就會拋出這個錯誤。在 JavaScript 的世界里,null 和 undefined 是不同的,null 代表這個對象是一個空的值,而 undefined 代表這個對象的值沒有定義。
這種錯誤較為常見的出現方式是,在頁面尚未加載完畢的時候,就直接操作 DOM,而實際上這個 DOM 節點現在還是一個 null。所以一定要等頁面加載完畢后,再操作 DOM:?
如果你的 JavaScript 代碼放在 CDN 上,那么這段代碼拋出的任何未捕獲的錯誤都會報腳本錯誤。這是瀏覽器的防止代碼跨源訪問的一種安全機制。
在 IE 瀏覽器上,當你調用一個未定義的方法時,就會出現這個錯誤。這個和下面介紹的 Chrome 瀏覽器上拋出的 “TypeError: ‘undefined’ is not a function”錯誤是一個類型。?
在 Chrome 瀏覽器上調用一個未定義的方法時,會拋出這個錯誤。?
?JavaScript 近些年的發展趨勢比較快,開發復雜度逐步增加,所以開發者可能會弄混當前的 this 究竟是指向哪個對象:?
這種情況是因為函數遞歸,超出了棧的最大大小限制,這個時候應該仔細檢查參數的變化,它可能沒有按照你想象的那樣變化:?
從一個未定義的變量上嘗試讀取它的長度屬性,會發生這樣的錯誤:?
?開發者錯誤的假定當前的數組一定是初始化后的,而實際上忘記傳遞參數是常有的事兒:?
我們不能在一個未定義的變量上,調用任何 set 或者 get 方法:?
在事件處理的時候,比較容易得到這樣的錯誤。舊版本的 IE 瀏覽器提供了一個全局可訪問的 event 變量,Chrome 自動將 event 對象綁定到回調函數上,Firefox 卻不會自動綁定。于是 jQuery 就為大家提供了一個統一的訪問事件對象的方式。?
大多數錯誤都是因為 null 或 undefined 引起的錯誤。使用靜態類型的 JavaScript 語言例如 TypeScript 可以有效幫你應對這些情況,它會給予你一些警告信息。希望大家在以后的編程中,盡量避開這些錯誤,它們看起來微不足道,卻又是大家最常犯的錯誤。
法: $.ajax([settings]);
php作為后臺的處理過程
ajax參數詳解:
data
類型:String
發送到服務器的數據。將自動轉換為請求字符串格式。GET 請求中將附加在 URL 后。查看 processData 選項說明以禁止此自動轉換。必須為 Key/Value 格式。如果為數組,jQuery 將自動為不同值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換為 '&foo=bar1&foo=bar2'。
dataFilter
類型:Function
給 Ajax 返回的原始數據的進行預處理的函數。提供 data 和 type 兩個參數:data 是 Ajax 返回的原始數據,type 是調用 jQuery.ajax 時提供的 dataType 參數。函數返回的值將由 jQuery 進一步處理。
dataType
類型:String
預期服務器返回的數據類型。如果不指定,jQuery 將自動根據 HTTP 包 MIME 信息來智能判斷,比如 XML MIME 類型就被識別為 XML。在 1.4 中,JSON 就會生成一個 JavaScript 對象,而 script 則會執行這個腳本。隨后服務器端返回的數據會根據這個值解析后,傳遞給回調函數。可用值:
"xml": 返回 XML 文檔,可用 jQuery 處理。
"html": 返回純文本 HTML 信息;包含的 script 標簽會在插入 dom 時執行。
"script": 返回純文本 JavaScript 代碼。不會自動緩存結果。除非設置了 "cache" 參數。注意:在遠程請求時(不在同一個域下),所有 POST 請求都將轉為 GET 請求。(因為將使用 DOM 的 script標簽來加載)
"json": 返回 JSON 數據 。
"jsonp": JSONP 格式。使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數。
"text": 返回純文本字符串
error
類型:Function
默認值: 自動判斷 (xml 或 html)。請求失敗時調用此函數。
有以下三個參數:XMLHttpRequest 對象、錯誤信息、(可選)捕獲的異常對象。
如果發生了錯誤,錯誤信息(第二個參數)除了得到 null 之外,還可能是 "timeout", "error", "notmodified" 和 "parsererror"。
這是一個 Ajax 事件。
global
類型:Boolean
是否觸發全局 AJAX 事件。默認值: true。設置為 false 將不會觸發全局 AJAX 事件,如 ajaxStart 或 ajaxStop 可用于控制不同的 Ajax 事件。
ifModified
類型:Boolean
僅在服務器數據改變時獲取新數據。默認值: false。使用 HTTP 包 Last-Modified 頭信息判斷。在 jQuery 1.4 中,它也會檢查服務器指定的 'etag' 來確定數據沒有被修改過。
jsonp
類型:String
在一個 jsonp 請求中重寫回調函數的名字。這個值用來替代在 "callback=?" 這種 GET 或 POST 請求中 URL 參數里的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 會導致將 "onJsonPLoad=?" 傳給服務器。
jsonpCallback
類型:String
為 jsonp 請求指定一個回調函數名。這個值將用來取代 jQuery 自動生成的隨機函數名。這主要用來讓 jQuery 生成度獨特的函數名,這樣管理請求更容易,也能方便地提供回調函數和錯誤處理。你也可以在想讓瀏覽器緩存 GET 請求的時候,指定這個回調函數名。
password
類型:String
用于響應 HTTP 訪問認證請求的密碼
processData
類型:Boolean
默認值: true。默認情況下,通過data選項傳遞進來的數據,如果是一個對象(技術上講只要不是字符串),都會處理轉化成一個查詢字符串,以配合默認內容類型 "application/x-www-form-urlencoded"。如果要發送 DOM 樹信息或其它不希望轉換的信息,請設置為 false。
scriptCharset
類型:String
只有當請求時 dataType 為 "jsonp" 或 "script",并且 type 是 "GET" 才會用于強制修改 charset。通常只在本地和遠程的內容編碼不同時使用。
success
類型:Function
請求成功后的回調函數。
參數:由服務器返回,并根據 dataType 參數進行處理后的數據;描述狀態的字符串。
這是一個 Ajax 事件。
traditional
類型:Boolean
如果你想要用傳統的方式來序列化數據,那么就設置為 true。請參考工具分類下面的 jQuery.param 方法。
timeout
類型:Number
設置請求超時時間(毫秒)。此設置將覆蓋全局設置。
type
類型:String
默認值: "GET")。請求方式 ("POST" 或 "GET"), 默認為 "GET"。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。
url
類型:String
默認值: 當前頁地址。發送請求的地址。
username
類型:String
用于響應 HTTP 訪問認證請求的用戶名。
xhr
類型:Function
需要返回一個 XMLHttpRequest 對象。默認在 IE 下是 ActiveXObject 而其他情況下是 XMLHttpRequest 。用于重寫或者提供一個增強的 XMLHttpRequest 對象。這個參數在 jQuery 1.3 以前不可用。
者:前端小混混 來源:前端先鋒
身為一名前端打工人,當然是經驗越多,在排查錯誤時會更容易。道理都懂,但仍然會在遇到問題時會不知道怎樣著手。
Chrome DevTools 中常見錯誤排查
Chrome 開發者工具的 Console 相當好用,最常使用的不外乎是通過 console.log展示出變量或運算的結果,如果符合預期則皆大歡喜。
但是一旦出現紅字幸災樂禍的告訴我們“你出錯了!”,這對我們來說無疑是一種挫折,在不知如何著手解決錯誤的時,只能反復地檢查自己的代碼,看看是不是有什么奇怪的地方,有時就算停在了錯誤地方也往往不知是什么意思,會因此花費大量的時間。
本文就來介紹在 Chrome 開發者工具中常見的錯誤反饋及排除技巧,讓你不再為了滿屏幕的紅字感到挫折,更能從中學習如何快速搜尋錯誤代碼。
注意:JavaScript 是屬于同步的編程語言,如果出現錯誤就會造成后面的代碼無法運行,當紅字沒有解決時,都有可能造成接下來的代碼行錯誤或是無法繼續運行。
錯誤類型:SyntaxError
SyntaxError 類型的錯誤通常是語法錯誤,遇到這種錯誤時建議通過你所用的 IDE 排查,比如 VSCode 能夠直接跳出這類型的錯誤提示。
如下圖,VSCode 用紅色波浪線提示 family 對象有錯誤,當出現錯誤時會建議不要只檢查當前行,錯誤可能會存在于上下文中(有可能跨多行的錯誤),這個例子中仔細檢查可以發現在'小明'后面少了一個逗號。
排查重點:使用主流的 IDE 例如 "VSCode" 進行排查
Uncaught SyntaxError: Unexpected identifier
var person={
name: '小明'
family: {
name: '小明家'
}
}
語法解析錯誤,因為在對象結構中缺少一個逗號,除了通過在 VSCode 中查看外,也可以直接通過 Chrome Console 切換到 Source 頁面查看錯誤行,并檢查此行的上下文中是否存在語法錯誤。
Uncaught SyntaxError: Unexpected end of input
function fn() {
console.log('這是一個函數');
console.log(fn);
語法解析錯誤:未預期的結束,這個例子中缺少結尾的大括號 },在編寫代碼時盡可能的維持正確的鎖緊,將代碼排列整齊之后更容易找到錯誤。
Uncaught SyntaxError: Unexpected token '}'
if (name)
console.log('立即執行函數')
};
語法解析錯誤:未預期的符號 },代碼結尾多了一個 } 符號導致環境運行錯誤,這個錯誤的排查方法與上面相同,盡可能將代碼排整齊并維持首尾符號的一致。
除此之外再推薦一個 VSCode 工具,可以為你的首尾標簽加上對應的色彩:
https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer
例子:代碼中成對的 {} 都會以相同的顏色展示。
Uncaught SyntaxError: Identifier 'a' has already been declared
let a;
let a;
語法解析錯誤:識別符號(在這里指的是變量)已經被聲明,應該避免重復聲明同一個變量,在 ES6 都禁止用 let、const 對變量進行重復聲明,直接排除即可。
錯誤類型:ReferenceError
ReferenceError 這類錯誤通常是指找不到引用,當出現這類錯誤時在 IDE 中不一定會提示現錯誤(除非安裝了 Linter),所以在代碼的運行階段才會看到這類錯誤。
排查重點:
ReferenceError: a is not defined
引用錯誤:由于變量 a 未定義,所以在使用這個變量時會出現未定義的提示,只要先定義好這個變量即可。
還有另一種很常見的情況,當引用外部包時出現 “包名 + is not defined”,這種情況通常是外部資源沒有被正確載入,應該確保該資源被正確的引入。
下面的例子就是因為 jQuery 沒有正確導入而導致的。
錯誤類型:TypeError
TypeError 是類型上的錯誤,同樣 IDE 也不會預先提示有錯誤,必須在執行時才會看到,這類型的錯誤通常是以下幾種:
排查重點:在獲取變量前先確認其當前的數據類型及結構
Uncaught TypeError: Cannot read property 'a' of undefined
var a;
console.log(a.a);
說明:在這個變量的值中無法找到其特定的屬性,例如在 undefined、null 的值上是找不到其它屬性的,如果無法確認該變量是否為 undefined,可以把代碼改成這樣:
if (typeof a !=='undefined') {
console.log(a.a);
}
Uncaught TypeError: console.log(...) is not a function
console.log('a')
(function() {
console.log('立即執行函數')
})()
說明:這代碼看起來是立即執行函數的錯誤,但是卻出現了 console.log(...) is not a function。這個錯誤主要是因為缺少了分號。
當遇到這類錯誤時只要在兩者之間補上分號即可。
console.log('a');
(function() {
console.log('立即執行函數')
})()
錯誤類型:RangeError
這是創建了超過長度上限的數組或執行了無法退出的遞歸函數所造成的錯誤,遇到這類問題需要重新檢查代碼的邏輯,是否消耗了過多的資源(內存或CPU資源)。
排查重點:需要重新檢查邏輯,如果有必要可先刪除部分代碼,先找出錯誤的片段后再進行除錯。
Uncaught RangeError: Maximum call stack size exceeded
(function a() {
a();
})();
說明:在函數調用時會產生一個函數調用棧,如果在遞歸的過程中超過上限則會產生錯誤。
這類錯誤也很常見,卻不容易找到出錯的原因,其主要原因是在遞歸時超過了環境的限制(使用框架時也很常見),如果遇到這錯誤建議改寫當前調用函數的方式。
總結
當 Chrome Console 報錯時要保持淡定,在編碼的過程中出現錯誤是很常見的,所謂的大佬與新手之間的區別之一就是遇到錯誤時的經驗,遇到錯誤時搞不清楚沒關系,這都是經驗的累積。只要積累足夠了,再遇到相同的問題時就能自然而然地輕松面對了。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。