亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

貓頭鷹的深夜翻譯:從1000+JS項(xiàng)目中匯總的10個(gè)最容易出現(xiàn)的錯(cuò)誤(以及如何解決)

eccozhou / 2527人閱讀

摘要:常出現(xiàn)的錯(cuò)誤前十位為了可讀性,錯(cuò)誤名稱進(jìn)行了一定的簡(jiǎn)寫(xiě)。讓我們深入了解每個(gè)錯(cuò)誤發(fā)生的原因以及解決方法。這個(gè)問(wèn)題很容易解決。當(dāng)未捕獲的錯(cuò)誤跨越違法跨域策略的域邊界時(shí),會(huì)發(fā)生腳本錯(cuò)誤。這是當(dāng)你在中試圖調(diào)用的方法時(shí)出現(xiàn)的錯(cuò)誤。

JavaScript常出現(xiàn)的錯(cuò)誤前十位

為了可讀性,錯(cuò)誤名稱進(jìn)行了一定的簡(jiǎn)寫(xiě)。讓我們深入了解每個(gè)錯(cuò)誤發(fā)生的原因以及解決方法。

1. Uncaught TypeError: Cannot Read Property

如果你是一名JavaScript開(kāi)發(fā)人員,你可能已經(jīng)記不清楚多少次看到這個(gè)錯(cuò)誤了。當(dāng)你讀取一個(gè)undefined對(duì)象的屬性或是調(diào)用其上的方法時(shí),就會(huì)出現(xiàn)這個(gè)錯(cuò)誤。你可以再Chrome Console中進(jìn)行測(cè)試。

導(dǎo)致這個(gè)問(wèn)題的原因有許多,最常見(jiàn)的是渲染UI組件時(shí)對(duì)state不恰當(dāng)?shù)某跏蓟W屛覀兛匆粋€(gè)真實(shí)APP中可能出現(xiàn)該情況的例子。我們選擇了React,但是這樣的不良初始化也適用于Angular,Vue或是其它的框架。

class Quiz extends Component {
  componentWillMount() {
    axios.get("/thedata").then(res => {
      this.setState({items: res.data});
    });
  }
  render() {
    return (
      
    {this.state.items.map(item =>
  • {item.name}
  • )}
); } }

這里要注意兩件重要的事情:

組件的state(比如 this.state)在生命周期開(kāi)始時(shí)為undefined。

當(dāng)你異步獲取數(shù)據(jù)的時(shí)候,component會(huì)在數(shù)據(jù)加載之前至少渲染一次 - 無(wú)論是否在constructor中獲取數(shù)據(jù),都會(huì)運(yùn)行componentWillMount或是componentDidMount。當(dāng)Quiz第一次渲染的時(shí)候,this.state.items為undefined。因此,item列表獲得的值為undefined,因此會(huì)報(bào)錯(cuò)"Uncaught TypeError: Cannot read property ‘map’ of undefined"。

這個(gè)問(wèn)題很容易解決。最簡(jiǎn)單的方法是,在構(gòu)造器里面將state初始化為一個(gè)合理的默認(rèn)值。

class Quiz extends Component {
  // Added this:
  constructor(props) {
    super(props);
    // Assign state itself, and a default value for items
    this.state = {
      items: []
    };
  }
  componentWillMount() {
    axios.get("/thedata").then(res => {
      this.setState({items: res.data});
    });
  }
  render() {
    return (
      
    {this.state.items.map(item =>
  • {item.name}
  • )}
); } }

這和你的項(xiàng)目中的代碼不一定完全相同,但是我們希望給你提供一個(gè)解決或是避免該問(wèn)題的思路。

2. TypeError: ‘undefined’ Is Not an Object (evaluating...)

這是一個(gè)在Safari中在undefined對(duì)象上訪問(wèn)屬性或方法時(shí)報(bào)的錯(cuò)。你可以在Safari的控制臺(tái)上進(jìn)行測(cè)試。這個(gè)錯(cuò)誤和之前在Chrome中出現(xiàn)的錯(cuò)誤是相同,只是報(bào)錯(cuò)信息不同。

3. TypeError: Null Is Not an Object (evaluating...)

這是在Safari中在訪問(wèn)null對(duì)象上的屬性或方法時(shí)報(bào)的錯(cuò)。

有趣的是,在JavaScript中,null和undefined是不同的,所以我們看到了兩個(gè)不同的報(bào)錯(cuò)信息。Undefined通常是指一個(gè)尚未賦值的變量,而null是指該變量的值為空。要想判斷二者不等,應(yīng)當(dāng)使用嚴(yán)格的相等操作符:

在真實(shí)世界中,這種錯(cuò)誤可能出現(xiàn)的原因之一是你試圖在元素加載完成之前訪問(wèn)DOM元素。對(duì)于空白的對(duì)象引用,DOM API會(huì)返回null。

任何對(duì)DOM元素進(jìn)行處理的JS代碼都應(yīng)該都在DOM元素創(chuàng)建完成之后進(jìn)行。JS代碼按照HTML中的規(guī)定按從上到下的順序進(jìn)行解釋。所以,如果在DOM元素之前存在標(biāo)簽,則腳本標(biāo)簽內(nèi)的JS代碼將在瀏覽器解析HTML頁(yè)面時(shí)執(zhí)行。如果在加載腳本之前尚未創(chuàng)建相關(guān)的DOM元素,就會(huì)出現(xiàn)此錯(cuò)誤。

在這個(gè)例子中,我們通過(guò)添加一個(gè)事件監(jiān)聽(tīng)器通知我們頁(yè)面已經(jīng)完成加載,來(lái)解決這個(gè)問(wèn)題。一旦addEventListener被觸發(fā),init()方法就能夠使用DOM元素。


4. (unknown): Script Error

當(dāng)未捕獲的JavaScript錯(cuò)誤跨越違法跨域策略的域邊界時(shí),會(huì)發(fā)生腳本錯(cuò)誤。比如,如果你將你的JavaScript代碼托管到CDN上,任何未被捕捉的錯(cuò)誤(沒(méi)有被try-catch塊捕獲,被冒泡至window.onerror處理器的錯(cuò)誤)將會(huì)被簡(jiǎn)單的報(bào)告為Script Error,不包含任何有用的信息。這是瀏覽器的一種安全措施,旨在防止跨域傳遞數(shù)據(jù)。

要想獲得真正的報(bào)錯(cuò)信息,做以下幾步:

1. 發(fā)送Access-Control-Allow-Origin頭

Access-Control-Allow-Origin設(shè)置為.來(lái)標(biāo)記該資源從任何域都可以正常訪問(wèn)。如果需要的話,也可以將其設(shè)置為自己的域名:比如,Access-Control-Allow-Origin: www.example.com。但是,處理多個(gè)域會(huì)變的棘手,而且如果你是出于緩存的問(wèn)題而使用CDN,那么這樣子的代價(jià)可能不值得。詳情參考這里

這里給出一些在不同的環(huán)境中設(shè)置header的例子:
Apache
在你存放JavaScript的文件夾中添加一個(gè).htacess文件,包含以下內(nèi)容:

Header add Access-Control-Allow-Origin "*"

Nginx
將add_header指令添加到為JavaScript文件提供服務(wù)的位置塊:

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

HAProxy
將以下內(nèi)容添加到提供JavaScript的asset backend

rspadd Access-Control-Allow-Origin: *
2. 在script標(biāo)簽上設(shè)置crossorigin="annonymous"屬性

在HTML中,對(duì)于每一個(gè)設(shè)置了Access-Control-Allow-Origin頭的腳本,在腳本的標(biāo)簽上添加crossorigin="anonymous"屬性。在將crossorigin屬性添加到腳本之前,請(qǐng)確保驗(yàn)證是否為腳本文件設(shè)置了header。在火狐瀏覽器中,如果設(shè)置了crossorigin屬性但是沒(méi)有設(shè)置Access-Control-Allow-Origin頭,該腳本不會(huì)執(zhí)行。

5. TypeError: Object Doesn’t Support Property

這是在IE瀏覽器中報(bào)的錯(cuò),當(dāng)你試圖調(diào)用一個(gè)undefined對(duì)象的方法時(shí):

這等價(jià)于Chrome中的TypeError: ‘undefined’ is not a function錯(cuò)誤。是的,不同的瀏覽器對(duì)相同的錯(cuò)誤會(huì)產(chǎn)生不同的報(bào)錯(cuò)信息。

對(duì)于使用JavaScript命名空間的Web程序,在IE上運(yùn)行時(shí)經(jīng)常會(huì)遇到這個(gè)錯(cuò)誤。當(dāng)這個(gè)錯(cuò)誤出現(xiàn)時(shí),99.9%的情況是因?yàn)镮E不能將當(dāng)前的命名空間的方法綁定到this關(guān)鍵字上。比如,假設(shè)你有一個(gè)JS命名空間Rollbar,其下有一個(gè)方法isAwesome()。通常在Rollbar命名空間下你會(huì)用如下的語(yǔ)法調(diào)用isAwesome方法:

this.isAwesome();

Chrome,F(xiàn)irfox和Opera都會(huì)愉快的接受這個(gè)語(yǔ)法。但是,IE并不會(huì)。因此,使用JS命名空間時(shí)最安全的選擇是始終以實(shí)際的命名空間作為前綴。

Rollbar.isAwesome();
6. TypeError: ‘undefined’ Is Not a Function

這是當(dāng)你在Chrome中試圖調(diào)用undefined的方法時(shí)出現(xiàn)的錯(cuò)誤。

隨著JavaScript的編程技巧和設(shè)計(jì)模式在這幾年來(lái)越來(lái)越復(fù)雜,在回調(diào)和閉包中自我引用范圍的擴(kuò)散也相應(yīng)的增加,導(dǎo)致對(duì)this出現(xiàn)困惑。
看下面這段代碼:

function testFunction() {
  this.clearLocalStorage();
  this.timer = setTimeout(function() {
    this.clearBoard();    // what is "this"?
  }, 0);
};

運(yùn)行上面的代碼會(huì)出現(xiàn)"Uncaught TypeError: undefined is not a function."報(bào)錯(cuò)。原因是當(dāng)你試圖調(diào)用setTimeout()方法時(shí),你實(shí)際上在調(diào)用window.setTimeout()方法。因此,一個(gè)匿名的函數(shù)傳入到setTimeout()方法中,該函數(shù)的上下文實(shí)際上是window對(duì)象,而window對(duì)象沒(méi)有clearBoard()方法。

一個(gè)傳統(tǒng)的,瀏覽器兼容的方案是將引用this存儲(chǔ)到一個(gè)變量中,該引用能夠被閉包繼承,如下:

function testFunction () {
  this.clearLocalStorage();
  var self = this;   // save reference to "this", while it"s still this!
  this.timer = setTimeout(function(){
    self.clearBoard();  
  }, 0);
};

在新版本的瀏覽器中,你可以使用bind()方法來(lái)傳遞引用:

function testFunction () {
  this.clearLocalStorage();
  this.timer = setTimeout(this.reset.bind(this), 0);  // bind to "this"
};
function reset(){
    this.clearBoard();    //back in the context of the right "this"!
};
7. Uncaught RangeError: Maximum Call Stack

這是在Chrome中出現(xiàn)的一種錯(cuò)誤。情況之一是當(dāng)你調(diào)用了一個(gè)沒(méi)有終止的遞歸方法:

當(dāng)你向方法傳了一個(gè)超越規(guī)定范圍的值也可能會(huì)出現(xiàn)這個(gè)報(bào)錯(cuò)。很多方法只接受特定范圍的值作為輸入。比如,Number.toExponential(digits)Number.toFixed(digits)只接受從0到20的數(shù)字,而Number.toPrecision(digits)則接受1到21的數(shù)字。

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

這是在Chrome中讀取一個(gè)undefined對(duì)象的length屬性時(shí)報(bào)的錯(cuò)。

你通??梢栽赼rray中找到length屬性,但是你也可能在array還沒(méi)有初始化或是變量名被隱藏在另一個(gè)上下文中時(shí)遇到這個(gè)錯(cuò)誤。讓我們用下面這個(gè)例子理解一下這個(gè)報(bào)錯(cuò):

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

當(dāng)你在方法中聲明參數(shù)時(shí),這些參數(shù)成為了局部變量。這意味著即使你有名為testArray的全局變量,方法中相同名稱的參數(shù)還是會(huì)被當(dāng)做局部變量。

你有兩種方法來(lái)結(jié)局這個(gè)問(wèn)題:

刪去方法聲明中的參數(shù)(如果你想要訪問(wèn)方法外的變量,就不需要在方法參數(shù)中聲明)

var testArray = ["Test"];
/* Precondition: defined testArray outside of a function */
function testFunction(/* No params */) {
    for (var i = 0; i < testArray.length; i++) {
      console.log(testArray[i]);
    }
}
testFunction();

向方法傳入聲明的參數(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

當(dāng)我們?cè)噲D訪問(wèn)一個(gè)undefined的變量時(shí),通常會(huì)返回undefined,而我們不能獲取或是設(shè)置undefined的屬性。這時(shí)候,應(yīng)用就會(huì)拋出“Uncaught TypeError cannot set property of undefined.”報(bào)錯(cuò)。

如果test對(duì)象不存在,也會(huì)拋出“Uncaught TypeError cannot set property of undefined.”

10. ReferenceError: Event Is Not Defined

當(dāng)你試圖訪問(wèn)的變量為undifined或是不在當(dāng)前作用域范圍內(nèi)時(shí),會(huì)拋出這個(gè)錯(cuò)誤:

如果你在使用事件處理系統(tǒng)時(shí)遇到這個(gè)報(bào)錯(cuò),請(qǐng)確保你將事件對(duì)象作為參數(shù)傳入了處理方法中。老的瀏覽器器如IE會(huì)提供一個(gè)全局的事件變量,而Chrome會(huì)自動(dòng)將事件變量附屬到handler上。Firfox不會(huì)自動(dòng)添加它。而類似jQuery之類的庫(kù)則試圖規(guī)范化這個(gè)行為??傊阕詈脤vent作為采納數(shù)傳入事件處理方法中:

document.addEventListener("mousemove", function (event) {
  console.log(event);
})
總結(jié)

看來(lái)大多數(shù)的錯(cuò)誤都是null或是undefined相關(guān)的錯(cuò)誤。如果你在使用編譯器的嚴(yán)格模式選項(xiàng),一個(gè)良好的類型檢查系統(tǒng)如Typescript能夠幫助你避免這些問(wèn)題。它會(huì)在一個(gè)預(yù)期類型沒(méi)有被定義時(shí)警告你。即便沒(méi)有Typescript, 它也能幫助我們使用防御性編程,在調(diào)用對(duì)象之前檢查對(duì)象是否是undefined。

我們希望你能夠?qū)W到一些新的內(nèi)容,并且在未來(lái)能夠避免這些錯(cuò)誤,也可能這個(gè)指南幫你解決了一些頭疼的問(wèn)題。無(wú)論如何,即便是最佳實(shí)踐,在編碼過(guò)程中還是會(huì)出現(xiàn)意料之外的錯(cuò)誤。了解影響用戶使用的錯(cuò)誤并且擁有可以快速解決問(wèn)題的工具是很重要的。


想要了解更多開(kāi)發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號(hào)!將會(huì)不定期的發(fā)放福利哦~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/107532.html

相關(guān)文章

  • 頭鷹深夜翻譯:JAVA中異常處理最佳實(shí)踐

    摘要:無(wú)需檢查的異常也是的子類。從低層拋出的需檢查異常強(qiáng)制要求調(diào)用方捕獲或是拋出該異常。當(dāng)前執(zhí)行的線程將會(huì)停止并報(bào)告該異常。單元測(cè)試允許我在使用中查看異常,并且作為一個(gè)可以被執(zhí)行的文檔來(lái)使用。不要捕獲最高層異常繼承的異常同樣是的子類。 前言 異常處理的問(wèn)題之一是知道何時(shí)以及如何去使用它。我會(huì)討論一些異常處理的最佳實(shí)踐,也會(huì)總結(jié)最近在異常處理上的一些爭(zhēng)論。 作為程序員,我們想要寫(xiě)高質(zhì)量的能夠解...

    W_BinaryTree 評(píng)論0 收藏0
  • 頭鷹深夜翻譯:持久化容器存儲(chǔ)

    摘要:如果我們的容器使用,文件如下在這個(gè)例子中,我們可以重復(fù)創(chuàng)建和銷毀,同一個(gè)持久存儲(chǔ)會(huì)被提供給新的,無(wú)論容器位于哪個(gè)節(jié)點(diǎn)上。 前言 臨時(shí)性存儲(chǔ)是容器的一個(gè)很大的買(mǎi)點(diǎn)。根據(jù)一個(gè)鏡像啟動(dòng)容器,隨意變更,然后停止變更重啟一個(gè)容器。你看,一個(gè)全新的文件系統(tǒng)又誕生了。 在docker的語(yǔ)境下: # docker run -it centos [root@d42876f95c6a /]# echo H...

    tianhang 評(píng)論0 收藏0
  • 頭鷹深夜翻譯:持久化容器存儲(chǔ)

    摘要:如果我們的容器使用,文件如下在這個(gè)例子中,我們可以重復(fù)創(chuàng)建和銷毀,同一個(gè)持久存儲(chǔ)會(huì)被提供給新的,無(wú)論容器位于哪個(gè)節(jié)點(diǎn)上。 前言 臨時(shí)性存儲(chǔ)是容器的一個(gè)很大的買(mǎi)點(diǎn)。根據(jù)一個(gè)鏡像啟動(dòng)容器,隨意變更,然后停止變更重啟一個(gè)容器。你看,一個(gè)全新的文件系統(tǒng)又誕生了。 在docker的語(yǔ)境下: # docker run -it centos [root@d42876f95c6a /]# echo H...

    xiao7cn 評(píng)論0 收藏0
  • 頭鷹深夜翻譯:Volatile原子性, 可見(jiàn)性和有序性

    摘要:有可能一個(gè)線程中的動(dòng)作相對(duì)于另一個(gè)線程出現(xiàn)亂序。當(dāng)實(shí)際輸出取決于線程交錯(cuò)的結(jié)果時(shí),這種情況被稱為競(jìng)爭(zhēng)條件。這里的問(wèn)題在于代碼塊不是原子性的,而且實(shí)例的變化對(duì)別的線程不可見(jiàn)。這種不能同時(shí)在多個(gè)線程上執(zhí)行的部分被稱為關(guān)鍵部分。 為什么要額外寫(xiě)一篇文章來(lái)研究volatile呢?是因?yàn)檫@可能是并發(fā)中最令人困惑以及最被誤解的結(jié)構(gòu)。我看過(guò)不少解釋volatile的博客,但是大多數(shù)要么不完整,要么難...

    Lionad-Morotar 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<