电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

來自1000多個項目的10大JavaScript錯誤淺析

瀏覽:69日期:2023-11-11 10:21:12

作為對社區(qū)開發(fā)者的回饋,我們從我們的數(shù)據(jù)庫里選出了10大來自數(shù)千個項目的JavaScript錯誤。我們將會給出產(chǎn)生這些錯誤的根源,以及如何避免再發(fā)生這些錯誤。如果能夠避免這些錯誤,就可以成為更好的開發(fā)者。

數(shù)據(jù)才是王道,我們通過收集和分析大量數(shù)據(jù)才選出了這10大JavaScript錯誤。我們收集每一個項目中出現(xiàn)的錯誤,并統(tǒng)計每一個錯誤發(fā)生的次數(shù)。我們根據(jù)錯誤代碼的指紋(fingerprint)對它們進行分組,也就是說,如果第二個錯誤與第一個是重復(fù)的,就把它們歸入同一個組。這樣就可以為用戶提供更好的視圖,而不是像查看繁瑣的日志文件那樣。

我們只關(guān)注影響面最大的那些錯誤。為此,我們統(tǒng)計了錯誤在各個公司的項目中發(fā)生的次數(shù),而不是錯誤發(fā)生的總次數(shù),因為如果是這樣的話,讀者就可能看到大量與他們不相干的統(tǒng)計信息。

以下是排名靠前的10大JavaScript錯誤:

來自1000多個項目的10大JavaScript錯誤淺析

出于可讀性方面的考慮,每個錯誤的描述經(jīng)過精簡。

1.Uncaught TypeError: Cannot read property

如果你是一名JavaScript開發(fā)者,對這個錯誤可能已經(jīng)熟視無睹。在Chrome里讀取未定義對象的屬性或調(diào)用未定義對象的方法時就會發(fā)生這個錯誤,在Chrome開發(fā)者控制臺可以很容易地重現(xiàn)這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

發(fā)生這個錯誤的原因有很多,其中最為常見的是,在渲染UI組件時沒有正確初始化狀態(tài)。我們通過一個真實的例子來看看這個錯誤是怎么發(fā)生的。我們選擇React作為示例,不過在其他框架(Angular、Vue等)中也是一樣的。

class Quiz extends Component { componentWillMount() { axios.get(’/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }}

這里要注意兩件事:

組件的狀態(tài)(如this.state)在一開始就是undefined。 如果是通過異步的方式來加載數(shù)據(jù),那么在數(shù)據(jù)加載進來之前,至少要渲染一次組件——不管是在構(gòu)造器、componentWillMout()還是componentDidMout()中加載數(shù)據(jù)。Quiz在進行第一次渲染時,this.state.items是undefined,那么ItemList就會得到undefined的數(shù)據(jù)項,這樣就會在控制臺看到這個錯誤——“Uncaught TypeError:Cannot read property ‘map’ of undefined”。

要解決這個問題其實很簡單,在構(gòu)造器里使用適當(dāng)?shù)哪J(rèn)值進行初始化。

class Quiz extends Component { // 增加這個: constructor(props) { super(props); // 使用空數(shù)組給state賦值 this.state = { items: [] }; } componentWillMount() { axios.get(’/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }} 2. TypeError: ’undefined’ is not an object

在Safari里讀取未定義對象的屬性或調(diào)用未定義對象的方法時就會發(fā)生這個錯誤,在Safari開發(fā)者控制臺可以很容易地重現(xiàn)這個錯誤。這個錯誤與發(fā)生在Chrome里的是差不多的,只是Safari為它提供了不同的錯誤信息。

來自1000多個項目的10大JavaScript錯誤淺析

3. TypeError: null is not an object

在Safari里讀取空(null)對象的屬性或調(diào)用空對象的方法時就會發(fā)生這個錯誤,在Safari開發(fā)者控制臺可以很容易地重現(xiàn)這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

有意思的是,在JavaScript里,null和undefined其實是不一樣的,所以我們會看到兩個不同的錯誤消息。undefined表示未賦值的變量,而null表示變量值為空。可以使用嚴(yán)格等于號來證明它們不是同一個東西。

來自1000多個項目的10大JavaScript錯誤淺析

在實際應(yīng)用當(dāng)中,在JavaScript里調(diào)用一個未加載的DOM元素就會出現(xiàn)這個錯誤。如果對象為空,DOM API就會返回null。

DOM元素需要在創(chuàng)建之后才能被訪問。JavaScript代碼是按照從上到下的順序進行解析的,所以,如果在DOM元素之前有一個標(biāo)簽包含了JavaScript代碼,瀏覽器在解析HTML時就會執(zhí)行這些代碼。在加載JavaScript之前,如果DOM元素沒有被創(chuàng)建,就會出現(xiàn)這個錯誤。

在這個例子里,我們可以通過添加一個事件監(jiān)聽器來解決這個問題,在頁面加載完畢時,事件監(jiān)聽器會通知我們。在addEventListener被觸發(fā)之后,init()方法就可以大膽地訪問DOM元素了。

<script> function init() { var myButton = document.getElementById('myButton'); var myTextfield = document.getElementById('myTextfield'); myButton.onclick = function() { var userName = myTextfield.value; } } document.addEventListener(’readystatechange’, function() { if (document.readyState === 'complete') { init(); } });</script><form> <input type='text' placeholder='Type your name' /> <input type='button' value='Go' /></form> 4. (unknown): Script error

跨域的未捕捉JavaScript異常會變成Script error。例如,假設(shè)JavaScript托管在CDN上,那么未捕捉的錯誤(錯誤沒有在try-catch里被捕獲,一路直上到了window.onerror里)就會顯示成“Script error”,而不是顯示具體的錯誤消息。這是瀏覽器出于安全方面的考慮,防止跨域傳遞數(shù)據(jù)。

要想獲得具體的錯誤信息,可以這樣做:

1).使用Access-Control-Allow-Origin

將Access-Control-Allow-Origin設(shè)置成“*”,表示該資源可以被任何一個域訪問。如果有必要,可以把“*”替換成你的域名,例如Access-Control-Allow-Origin: www.example.com。不過,如果使用了CDN,那么要支持多個域名可能就會得不償失,因為CDN存在緩存問題。

下面是在各種環(huán)境如何設(shè)置該字段的示例:

Apache

在JavaScript文件所在的目錄創(chuàng)建一個叫作.htaccess的文件,并加入如下內(nèi)容:

Header add Access-Control-Allow-Origin “*'

Nginx

在JavaScript對應(yīng)的location配置代碼塊中加入add_header指令:

location ~ ^/assets/ { add_header Access-Control-Allow-Origin *;}

HAProxy

在JavaScript文件對應(yīng)的backend配置塊中加入如下內(nèi)容:

rspadd Access-Control-Allow-Origin: *

2). 在script標(biāo)簽里設(shè)置crossorigin=“anonymous”

在每個設(shè)置了Access-Control-Allow-Origin字段的HTML頁面里,將它們的script標(biāo)簽的crossorigin屬性設(shè)置為“anonymous”。在Firefox里,如果出現(xiàn)了crossorigin,但沒有設(shè)置Access-Control-Allow-Origin,JavaScript腳本就不會被執(zhí)行。

5. TypeError: Object doesn’t support property

在IE里讀取未定義對象的屬性或調(diào)用未定義對象的方法時就會發(fā)生這個錯誤,在IE開發(fā)者控制臺可以很容易地重現(xiàn)這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

這個錯誤與Chrome里的“TypeError: ‘undefined’ is not a function”是同一個東西。不同的瀏覽器為相同的錯誤提供的錯誤消息可能是不一樣的。

在IE里使用JavaScript的命名空間時,就很容易碰到這個錯誤。發(fā)生這個錯誤十有八九是因為IE無法將當(dāng)前命名空間里的方法綁定到this關(guān)鍵字上。例如,假設(shè)有個命名空間Rollbar,它有一個方法叫isAwesome()。在Rollbar命名空間中,可以直接使用this關(guān)鍵字來調(diào)用這個方法:

this.isAwesome();

在Chrome、Firefox和Opera中這樣做都是沒有問題的,但在IE中就不行。所以,最安全的做法是指定全命名空間:

Rollbar.isAwesome(); 6. TypeError: ‘undefined’ is not a function

在Chrome里調(diào)用一個未定義的函數(shù)時就會發(fā)生這個錯誤,可以在Chrome開發(fā)者控制臺和Mozilla開發(fā)者控制臺重現(xiàn)這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

近年來,JavaScript的編碼技術(shù)和設(shè)計模式變得日趨復(fù)雜,回調(diào)和閉包中的自引用情況越來越普遍,讓人搞不清楚代碼中的this/that表示的是什么意思。

比如下面這段代碼:

function testFunction() { this.clearLocalStorage(); this.timer = setTimeout(function() { this.clearBoard(); // 這里的”this'是指什么? }, 0);};

執(zhí)行上面的代碼會出現(xiàn)這樣的錯誤:“Uncaught TypeError: undefined is not a function”。因為在調(diào)用setTimeout()方法時,實際上是在調(diào)用window.setTimeout()。傳給setTimeout()的匿名函數(shù)的上下文實際上是window,而window并不包含clearBoard()方法。

對于舊瀏覽器,以往的解決辦法是將this賦值給某個變量,然后在閉包里使用這個變量。例如:

function testFunction () { this.clearLocalStorage(); var self = this; // 將this賦值給self this.timer = setTimeout(function(){ self.clearBoard(); }, 0);};

在新瀏覽器中,可以使用bind()方法來傳遞引用:

function testFunction () { this.clearLocalStorage(); this.timer = setTimeout(this.reset.bind(this), 0); // 綁定到 ’this’};function testFunction(){ this.clearBoard(); // 以’this’作為上下文}; 7. Uncaught RangeError: Maximum call stack

在Chrome里,有幾種情況會發(fā)生這個錯誤,其中一個就是無限遞歸調(diào)用一個函數(shù)。這個錯誤可以在Chrome開發(fā)者控制臺重現(xiàn)。

來自1000多個項目的10大JavaScript錯誤淺析

當(dāng)傳給函數(shù)的值超出可接受的范圍時也會出現(xiàn)這個錯誤。很多函數(shù)只接受指定范圍的數(shù)值,例如,Number.toExponential(digits)和Number.toFixed(digits)只接受0到20的數(shù)值,而Number.toPrecision(digits)只接受1到21的數(shù)值。

var a = new Array(4294967295); //OKvar b = new Array(-1); //range errorvar num = 2.555555;document.writeln(num.toExponential(4)); //OKdocument.writeln(num.toExponential(-2)); //range error!num = 2.9999;document.writeln(num.toFixed(2)); //OKdocument.writeln(num.toFixed(25)); //range error!num = 2.3456;document.writeln(num.toPrecision(1)); //OKdocument.writeln(num.toPrecision(22)); //range error! 8. TypeError: Cannot read property ‘length’

在Chrome里讀取undefined變量的length屬性時會發(fā)生這個錯誤,這個錯誤可以在Chrome開發(fā)者控制臺重現(xiàn)。

來自1000多個項目的10大JavaScript錯誤淺析

length是數(shù)組的屬性,但如果數(shù)組沒有初始化或者數(shù)組的變量名被另一個上下文隱藏起來的話,訪問length屬性就會發(fā)生這個錯誤。例如:

var testArray= ['Test'];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction();

函數(shù)的參數(shù)名會覆蓋全局的變量名。也就是說,全局的testArray被函數(shù)的參數(shù)名覆蓋了,所以在函數(shù)體里訪問到的是本地的testArray,但本地并沒有定義testArray,所以出現(xiàn)了這個錯誤。

有兩種方法可用于解決這個問題:

1). 將函數(shù)的參數(shù)名移除(這就表示函數(shù)里要訪問的變量已經(jīng)在函數(shù)外面定義好了,所以函數(shù)不需要參數(shù)):

var testArray = ['Test'];/* 前提是要在函數(shù)外面定義好testArray */function testFunction(/* No params */) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction();

2). 在調(diào)用函數(shù)時將變量傳遞進去:

var testArray = ['Test'];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction(testArray); 9. Uncaught TypeError: Cannot set property

我們無法對undefined變量進行賦值或讀取操作,否則的話會拋出“Uncaught TypeError: cannot set property of undefined”異常。

例如,在Chrome中:

來自1000多個項目的10大JavaScript錯誤淺析

如果test對象不存在,就會拋出“Uncaught TypeError: cannot set property of undefined”異常。

10. ReferenceError: event is not defined

在訪問一個未定義的對象或超出當(dāng)前作用域的對象時就會發(fā)生這個錯誤,這個錯誤可以在Chrome開發(fā)者控制臺重現(xiàn)。

來自1000多個項目的10大JavaScript錯誤淺析

如果在進行事件處理時遇到這個錯誤,請確保事件對象被作為參數(shù)傳入到函數(shù)當(dāng)中。舊瀏覽器(IE)提供了全局的event變量,但并不是所有的瀏覽器都會這樣。盡管jQuery嘗試對這種行為進行規(guī)范化,但最好還是使用傳給函數(shù)的event對象:

function myFunction(event) { event = event.which || event.keyCode; if(event.keyCode===13){ alert(event.keyCode); }} 結(jié)論

我們希望這些內(nèi)容能夠幫助大家在未來避免這些錯誤,解決大家的痛點。不過,即使有了這些最佳實踐,在生產(chǎn)環(huán)境中仍然會出現(xiàn)各種不可預(yù)期的錯誤。關(guān)鍵是要及時發(fā)現(xiàn)那些影響用戶體驗的錯誤,并使用適當(dāng)?shù)墓ぞ呖焖俳鉀Q這些問題。

查看英文原文: Top 10 JavaScript errors from 1000+ projects (and how to avoid them)

感謝徐川對本文的審校。

來自:http://www.infoq.com/cn/articles/top-10-javascript-errors

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司_龙门加工中心-数控龙门加工中心厂家价格-山东海特数控机床有限公司 | 挤出机_橡胶挤出机_塑料挤出机_胶片冷却机-河北伟源橡塑设备有限公司 | 【MBA备考网】-2024年工商管理硕士MBA院校/报考条件/培训/考试科目/提前面试/考试/学费-MBA备考网 | CTAB,表面活性剂1631溴型(十六烷基三甲基溴化铵)-上海升纬化工原料有限公司 | 烘箱-工业烘箱-工业电炉-实验室干燥箱 - 苏州华洁烘箱制造有限公司 | 滚塑PE壳体-PE塑料浮球-警示PE浮筒-宁波君益塑业有限公司 | 锥形螺带干燥机(新型耙式干燥机)百科-常州丰能干燥工程 | 南京泽朗生物科技有限公司-液体饮料代加工_果汁饮料代加工_固体饮料代加工 | 双段式高压鼓风机-雕刻机用真空泵-绍兴天晨机械有限公司 | 超细粉碎机|超微气流磨|气流分级机|粉体改性设备|超微粉碎设备-山东埃尔派粉碎机厂家 | 深圳成考网-深圳成人高考报名网 深圳工程师职称评定条件及流程_深圳职称评审_职称评审-职称网 | 成都珞石机械 - 模温机、油温机、油加热器生产厂家 | 水稻烘干机,小麦烘干机,大豆烘干机,玉米烘干机,粮食烘干机_巩义市锦华粮食烘干机械制造有限公司 水环真空泵厂家,2bv真空泵,2be真空泵-淄博真空设备厂 | 上海电子秤厂家,电子秤厂家价格,上海吊秤厂家,吊秤供应价格-上海佳宜电子科技有限公司 | 巨野月嫂-家政公司-巨野县红墙安康母婴护理中心 | 盘扣式脚手架-附着式升降脚手架-移动脚手架,专ye承包服务商 - 苏州安踏脚手架工程有限公司 | 农业仪器网 - 中国自动化农业仪器信息交流平台 | 路面机械厂家| 垃圾清运公司_环卫保洁公司_市政道路保洁公司-华富环境 | 济南品牌包装设计公司_济南VI标志设计公司_山东锐尚文化传播 | 菲希尔X射线测厚仪-菲希尔库伦法测厚仪-无锡骏展仪器有限责任公司 | 液氮罐(生物液氮罐)百科-无锡爱思科 | 开云(中国)Kaiyun·官方网站-登录入口 | 带式压滤机_污泥压滤机_污泥脱水机_带式过滤机_带式压滤机厂家-河南恒磊环保设备有限公司 | 半容积式换热器_北京浮动盘管换热器厂家|北京亿丰上达 | 山东钢衬塑罐_管道_反应釜厂家-淄博富邦滚塑防腐设备科技有限公司 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 低气压试验箱_高低温低气压试验箱_低气压实验箱 |林频试验设备品牌 | 河北码上网络科技|邯郸小程序开发|邯郸微信开发|邯郸网站建设 | 玻璃瓶厂家_酱菜瓶厂家_饮料瓶厂家_酒瓶厂家_玻璃杯厂家_徐州东明玻璃制品有限公司 | 广西绿桂涂料--承接隔热涂料、隔音涂料、真石漆、多彩仿石漆等涂料工程双包施工 | 圈酒招商网【jiushuitv.com】_酒水招商_代理_加盟平台 | lcd条形屏-液晶长条屏-户外广告屏-条形智能显示屏-深圳市条形智能电子有限公司 | MVR蒸发器厂家-多效蒸发器-工业废水蒸发器厂家-康景辉集团官网 | 冷轧机|两肋冷轧机|扁钢冷轧机|倒立式拉丝机|钢筋拔丝机|收线机-巩义市华瑞重工机械制造有限公司 | 棉柔巾代加工_洗脸巾oem_一次性毛巾_浴巾生产厂家-杭州禾壹卫品科技有限公司 | 山东活动策划|济南活动公司|济南公关活动策划-济南锐嘉广告有限公司 | 警方提醒:赣州约炮论坛真的安全吗?2025年新手必看的网络交友防坑指南 | 真空干燥烘箱_鼓风干燥箱 _高低温恒温恒湿试验箱_光照二氧化碳恒温培养箱-上海航佩仪器 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 | 全自动真空上料机_粉末真空上料机_气动真空上料机-南京奥威环保科技设备有限公司 |