Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产精品嫩草影院免费,99热这里只有精品5,亚洲自拍偷拍区

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          10 種 JavaScript 最常見的錯誤

          10 種 JavaScript 最常見的錯誤

          看了數(shù)千個項目后,發(fā)現(xiàn)了 10 個最常見的 JavaScript 錯誤。我們會告訴你什么原因?qū)е铝诉@些錯誤,以及如何防止這些錯誤發(fā)生。如果你能夠避免落入這些 “陷阱”,你將會成為一個更好的開發(fā)者。

          一、Uncaught TypeError: Cannot read property

          如果你是一個 JavaScript 開發(fā)人員,可能你看到這個錯誤的次數(shù)比你敢承認的要多。當你讀取一個未定義的對象的屬性或調(diào)用其方法時,這個錯誤會在 Chrome 中出現(xiàn)。 您可以很容易的在 Chrome 開發(fā)者控制臺中進行測試。

          發(fā)生這種情況的原因很多,但常見的一種是在渲染 UI 組件時對于狀態(tài)的初始化操作不當。

          我們來看一個在真實應(yīng)用程序中發(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>
           );
           }
          }
          

          兩個重要的流程:

          1. 組件的狀態(tài)(例如 this.state)開始于 undefined。
          2. 當異步獲取數(shù)據(jù)時,不管它是在構(gòu)造函數(shù) componentWillMount 還是 componentDidMount 中獲取的,組件在數(shù)據(jù)加載之前至少會呈現(xiàn)一次,當 Quiz 第一次呈現(xiàn)時,this.state.items 是 undefined。

          這很容易解決。最簡單的方法:在構(gòu)造函數(shù)中初始化 state。

          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 (
           <ul>
           {this.state.items.map(item=>
           <li key={item.id}>{item.name}</li>
           )}
           </ul>
           );
           }
          }
          

          在你的應(yīng)用程序中的具體代碼可能是不同的,但我們希望我們已經(jīng)給你足夠的線索,以解決或避免在你的應(yīng)用程序中出現(xiàn)的這個問題。如果還沒有,請繼續(xù)閱讀,因為我們將在下面覆蓋更多相關(guān)錯誤的示例。

          2、 TypeError: ‘undefined’ is not an object

          這是在 Safari 中讀取屬性或調(diào)用未定義對象上的方法時發(fā)生的錯誤。您可以在 Safari Developer Console 中輕松測試。這與第一點中提到的 Chrome 的錯誤基本相同,但 Safari 使用了不同的錯誤消息提示語。

          3、 TypeError: null is not an object

          這是在 Safari 中讀取屬性或調(diào)用空對象上的方法時發(fā)生的錯誤。 您可以在 Safari Developer Console 中輕松測試。

          有趣的是,在 JavaScript 中,null 和 undefined 是并不同,這就是為什么我們看到的是兩個不同的錯誤信息。

          undefined 通常是一個尚未分配的變量,而 null 表示該值為空。 要驗證它們不相等,請嘗試使用嚴格的相等運算符===

          在我們工作中,這種錯誤可能發(fā)生的一種場景是:如果在加載元素之前嘗試在 JavaScript 中使用元素。 因為 DOM API 對于空白的對象引用返回值為 null。

          任何執(zhí)行和處理 DOM 元素的 JS 代碼都應(yīng)該在創(chuàng)建 DOM 元素之后執(zhí)行。

          JS 代碼按照 HTML 中的規(guī)定從上到下進行解釋。 所以,如果 DOM 元素之前有一個標簽,腳本標簽內(nèi)的 JS 代碼將在瀏覽器解析 HTML 頁面時執(zhí)行。 如果在加載腳本之前尚未創(chuàng)建 DOM 元素,則會出現(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" id="myTextfield" placeholder="Type your name" />
           <input type="button" id="myButton" value="Go" />
          </form>
          

          4、 (unknown): Script error

          當未捕獲的 JavaScript 錯誤(通過 window.onerror 處理程序引發(fā)的錯誤,而不是捕獲在 try-catch 中)被瀏覽器的跨域策略限制時,會產(chǎn)生這類的腳本錯誤。 例如,如果您將您的 JavaScript 代碼托管在 CDN 上,則任何未被捕獲的錯誤將被報告為“腳本錯誤” 而不是包含有用的堆棧信息。這是一種瀏覽器安全措施,旨在防止跨域傳遞數(shù)據(jù),否則將不允許進行通信。

          要獲得真正的錯誤消息,請執(zhí)行以下操作:

          1. 設(shè)置 ‘Access-Control-Allow-Origin’ 頭部

          將 Access-Control-Allow-Origin 標頭設(shè)置為 * 表示可以從任何域正確訪問資源。

          在 Nginx 中設(shè)置如下:

          將 add_header 指令添加到提供 JavaScript 文件的位置塊中:

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

          2. 在 <script> 中設(shè)置 crossorigin="anonymous"

          在您的 HTML 代碼中,對于您設(shè)置了 Access-Control-Allow-Origin 的每個腳本,在 script 標簽上設(shè)置 crossorigin=“anonymous”。在腳本標記中添加 crossorigin 屬性之前,請確保驗證上述 header 正確發(fā)送。

          在 Firefox 中,如果存在crossorigin屬性,但Access-Control-Allow-Origin頭不存在,則腳本將不會執(zhí)行。

          5、 TypeError: Object doesn’t support property

          這是您在調(diào)用未定義的方法時發(fā)生在 IE 中的錯誤。 您可以在 IE 開發(fā)者控制臺中進行測試。

          這相當于 Chrome 中的 “TypeError:”undefined“ is not a function” 錯誤。

          是的,對于相同的邏輯錯誤,不同的瀏覽器可能具有不同的錯誤消息。

          對于使用 JavaScript 命名空間的 Web 應(yīng)用程序,這是一個 IE 瀏覽器的常見的問題。 在這種情況下,99.9% 的原因是 IE 無法將當前名稱空間內(nèi)的方法綁定到 this 關(guān)鍵字。

          例如:如果你 JS 中有一個命名空間 Rollbar 以及方法 isAwesome。 通常,如果您在 Rollbar 命名空間內(nèi),則可以使用以下語法調(diào)用 isAwesome 方法:

          this.isAwesome();
          

          Chrome,F(xiàn)irefox 和 Opera 會欣然接受這個語法。 但是 IE 卻不會。 因此,使用 JS 命名空間時最安全的選擇是始終以實際名稱空間作為前綴。

          Rollbar.isAwesome();
          

          6、 TypeError: ‘undefined’ is not a function

          當您調(diào)用未定義的函數(shù)時,這是 Chrome 中產(chǎn)生的錯誤。 您可以在 Chrome 開發(fā)人員控制臺和 Mozilla Firefox 開發(fā)人員控制臺中進行測試。

          function clearBoard(){
           alert("Cleared");
          }
          document.addEventListener("click", function(){
           this.clearBoard(); // what is “this” ?
          });
          

          執(zhí)行上面的代碼會導致以下錯誤:

          “Uncaught TypeError:this.clearBoard is not a function”。

          原因應(yīng)該是清楚的,即執(zhí)行上下文不理解導致的指向錯誤。

          7、 Uncaught RangeError

          當你調(diào)用一個不終止的遞歸函數(shù)就會發(fā)生這種錯誤。您可以在 Chrome 開發(fā)者控制臺中進行測試。

          此外,如果您將值傳遞給超出范圍的函數(shù),也可能會發(fā)生這種情況。

          許多函數(shù)只接受其輸入值的特定范圍的數(shù)字。 例如:

          1. toExponential(digits) 和 toFixed(digits) 接受 0 到 100
          2. toPrecision(digits) 接受 1 到 100
          var num=2.555555;
          console.log(num.toExponential(4)); //OK
          console.log(num.toExponential(-2)); //range error!
          console.log(num.toFixed(2)); //OK
          console.log(num.toFixed(105)); //range error!
          console.log(num.toPrecision(1)); //OK
          console.log(num.toPrecision(0)); //range error!
          

          8、 TypeError: Cannot read property ‘length’

          這是 Chrome 中發(fā)生的錯誤,因為讀取未定義變量的長度屬性。 您可以在 Chrome 開發(fā)者控制臺中進行測試。

          您通常會在數(shù)組中找到定義的長度,但是如果數(shù)組未初始化或者變量在另一個上下文中,則可能會遇到此錯誤。讓我們用下面的例子來理解這個錯誤。

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

          執(zhí)行以上代碼會報錯:

          Cannot read property 'length' of undefined

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

          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();
          

          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,我們不能獲取或設(shè)置任何未定義的屬性。 在這種情況下會將拋出 “Uncaught TypeError: Cannot set property”。

          10. ReferenceError: event is not defined

          當您嘗試訪問未定義的變量或超出當前作用域的變量時,會引發(fā)此錯誤。 您可以在 Chrome 瀏覽器中測試。

          如果在使用 event 時遇到此錯誤,請確保使用傳入的事件對象作為參數(shù)。像 IE 這樣的舊瀏覽器提供了一個全局變量事件,但并不是所有瀏覽器都支持。

          document.addEventListener("mousemove", function (event) {
           console.log(event);
          })
          

          總結(jié)

          我們看到上面的 10 個最常見的錯誤,其實所涉及的知識點并不難。當你認真讀過《你不知道的 JavaScript》上卷后,這些錯誤基本就不會再出現(xiàn)了。當然,歸根結(jié)底還是要有扎實的 javascript 基礎(chǔ),理解底層原理和實現(xiàn)。

          么是JS延遲加載?

          JS延遲加載,也就是等頁面加載完成之后再加載JavaScript文件

          為什么讓JS實現(xiàn)延遲加載?

          js的延遲加載有助于提高頁面的加載速度。

          Js延遲加載的方式有哪些?一般有以下幾種方式:

          ·defer屬性

          ·async屬性

          ·動態(tài)創(chuàng)建DOM方式

          ·使用jQuery的getScript方法

          ·使用setTimeout延遲方法

          ·讓JS最后加載

          1、defer屬性

          HTML 4.01為<script>標簽定義了defer屬性。標簽定義了defer屬性元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行標簽定義了defer屬性。

          用途:表明腳本在執(zhí)行時不會影響頁面的構(gòu)造。也就是說,腳本會被延遲到整個頁面都解析完畢之后再執(zhí)行在<script>元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行

          <!DOCTYPE html>
          <html>
          <head>
          	<script src="test1.js" defer="defer"></script>
          	<script src="test2.js" defer="defer"></script>
          </head>
          <body>
          <!--這里放內(nèi)容-->
          </body>
          </html>

          說明:雖然<script>元素放在了<head>元素中,但包含的腳本將延遲瀏覽器遇到</html>標簽后再執(zhí)行HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行。在現(xiàn)實當中,延遲腳本并不一定會按照順序執(zhí)行defer屬性只適用于外部腳本文件。支持HTML5的實現(xiàn)會忽略嵌入腳本設(shè)置的defer屬性

          2、async屬性

          HTML5 為<script>標簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。標簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。

          目的:不讓頁面等待腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。異步腳本一定會在頁面 load 事件前執(zhí)行。不能保證腳本會按順序執(zhí)行

          <!DOCTYPE html>
          <html>
          	<head>
          		<script src="test1.js" async></script>
          		<script src="test2.js" async></script>
          	</head>
          <body>
          <!--這里放內(nèi)容-->
          </body>
          </html>

          async和defer一樣,都不會阻塞其他資源下載,所以不會影響頁面的加載。

          缺點:不能控制加載的順序

          3、動態(tài)創(chuàng)建DOM方式

          //這些代碼應(yīng)被放置在</ body>標簽前(接近HTML文件底部)
          <script type="text/javascript">
          	function downloadJSAtOnload() {
          		varelement=document .createElement("script");
          		element.src="defer.js";
          		document.body.appendChild(element);
          	}
          	if (window. addEventListener)
          		window.addEventListener("load" ,downloadJSAtOnload, false);
          	else if (window.attachEvent)
          		window.attachEvent("onload", downloadJSAtOnload) ;
          	else
          		window. onload=downloadJSAtOnload;
          </script>

          4、使用jQuery的getScript()方法

          $.getScript("outer.js" , function(){	//回調(diào)函數(shù),成功獲取文件后執(zhí)行的函數(shù)
          	console.log(“腳本加載完成")
          });

          5、使用setTimeout延遲方法的加載時間延遲加載js代碼,給網(wǎng)頁加載留出更多時間

          <script type="text/javascript" >
          	function A(){
          		$.post("/1ord/1ogin" ,{name:username,pwd:password},function(){
          			alert("Hello");
          		});
          	}
          	$(function (){
          		setTimeout('A()', 1000);	//延遲1秒
          	})
          </script>

          6、讓JS最后加載

          把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度例如引入外部js腳本文件時,如果放入html的head中,則頁面加載前該js腳本就會被加載入頁面,而放入body中,則會按照頁面從上倒下的加載順序來運行JavaScript的代碼。所以我們可以把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度。

          上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這里的解決方案將是來自Google幫助頁面的推薦方案。

          //這些代碼應(yīng)被放置在</body>標簽前(接近HTML文件底部)
          
          <script type="text/javascript">
          	function downloadJSAtonload() {
          		var element=document.createElement("script");
          		element.src="defer.js";
          		document.body.appendChild(element);
          	}
          	if (window.addEventListener)
          		window.addEventListener("load", downloadJSAtOnload, false);
          	else if (window.attachEvent )
          		window.attachEvent("onload", downloadJSAtonload);
          	else window.onload=downloadJSAtOnload;
          </script>

          這段代碼意思等到整個文檔加載完后,再加載外部文件“defer.js”。

          使用此段代碼的步驟:

          6.1)復制上面代碼

          6.2)粘貼代碼到HTML的標簽前 (靠近HTML文件底部)

          6.3)修改“defer.js”為你的外部JS文件名

          6.4)確保文件路徑是正確的。例如:如果你僅輸入“defer.js”,那么“defer.js”文件一定與HTML文件在同一文件夾下。

          注意:

          這段代碼直到文檔加載完才會加載指定的外部js文件。因此,不應(yīng)該把那些頁面正常加載需要依賴的javascript代碼放在這里。而應(yīng)該將JavaScript代碼分成兩組。一組是因頁面需要而立即加載的javascript代碼,另外一組是在頁面加載后進行操作的javascript代碼(例如添加click事件。

          本已經(jīng)過原作者 Viduni Wickramarachchi 授權(quán)翻譯。

          你是否經(jīng)歷過JavaScript中的某些值比較沒有得到預期結(jié)果的情況?

          看下面的情況:

          即使[]==0結(jié)果為真,if[]條件也沒有根據(jù)結(jié)果執(zhí)行。有沒有想過為什么會這樣?

          本文主要說明這些值比較的工作原理以及影響它們的因素。在深入解釋之前,大家要熟悉一個概念:類型轉(zhuǎn)換。

          什么是 JavaScript 類型轉(zhuǎn)換?

          這也稱為類型強制。對于不熟悉此概念的人來說,它只是將值從一種數(shù)據(jù)類型自動轉(zhuǎn)換為另一種數(shù)據(jù)類型。

          看個例子,大家會更清楚明白。

          在此示例中,定義的兩個變量具有兩種類型;字符串和數(shù)字。但是,當我們使用 ==(非嚴格比較)進行比較時,結(jié)果為true。原因是當我們使用==比較這兩個時,JavaScript 會自動嘗試將String類型轉(zhuǎn)換為Number類型以產(chǎn)生結(jié)果。這是一種強制轉(zhuǎn)換。

          JavaScript中有多種強制類型。

          • Number conversions
          • String conversions
          • Boolean conversions
          • 對象的類型轉(zhuǎn)換

          類型強制轉(zhuǎn)換都是好的嗎?

          在上述情況下,類型轉(zhuǎn)換沒有害處。但是,在許多情況下,類型強制會導致問題。

          我們看下面例子。

          在這里,JavaScript已將Number類型轉(zhuǎn)換為String。這與相等比較中發(fā)生的情況相反。我們預期的結(jié)果是450。但是,我們得到了String輸出。

          現(xiàn)在,我們對類型轉(zhuǎn)換以及為什么要避免使用類型轉(zhuǎn)換有了清晰的了解,讓我們看看如何避免類型轉(zhuǎn)換。這是本文最重要的部分。因此,請坐下來,喝咖啡并集中精力

          如何避免 JavaScript 類型轉(zhuǎn)換

          1. 對數(shù)學運算使用顯式轉(zhuǎn)換

          如果你需要對用戶輸入或任何其他值使用數(shù)學運算,則在執(zhí)行該運算之前,自己進行一次顯式轉(zhuǎn)換會更安全。這樣,可以避免任何意外行為。

          2. 使用模板字面值連接字符串,而不是+

          如果需要連接兩個數(shù)字,則使用模板文字會更安全。特別是不確定值的類型。

          也可以使用顯式轉(zhuǎn)換來導出相同的結(jié)果。

          3.當比較值時,使用嚴格的比較(===)

          前面我們看到,當使用==時,JavaScript 會執(zhí)行隱式類型轉(zhuǎn)換,這會導致不一致的結(jié)果。因此,在我們的生產(chǎn)代碼中使用它是不安全的。

          為了得出預期的結(jié)果,應(yīng)該始終使用===進行比較。三等號隱含地表示:

          我可以同時了解變量的值和類型

          因此,如果將數(shù)字和字符串與值進行比較,結(jié)果將是false,因為它也會考慮變量的類型。

          這是獲得預期一致結(jié)果的更安全的方法。

          在JavaScript中,數(shù)據(jù)類型有兩種變體。

          • 原始值(字符串、數(shù)字等)
          • 非原始值(數(shù)組、對象)

          到目前為止,我們已經(jīng)討論了原始數(shù)據(jù)類型的類型轉(zhuǎn)換。我提供的第一個示例涉及非原始數(shù)據(jù)類型,例如數(shù)組。

          所有非原始數(shù)據(jù)類型都有一個名為.toPrimitive()的內(nèi)置函數(shù)。比較非原始值和原始值時,此函數(shù)會自動將非原始類型轉(zhuǎn)換為原始類型。在我們看過的第一個示例中,當使用此函數(shù)進行非嚴格比較時,空數(shù)組將轉(zhuǎn)換為空字符串。確切地說,用于執(zhí)行此轉(zhuǎn)換的確切函數(shù)是toString()。因此,空數(shù)組(將轉(zhuǎn)換為空字符串)等于0。

          正如我們前面所看到的,當在if條件中檢查空數(shù)組時,將執(zhí)行條件中的行。但是,如果空數(shù)組隱式轉(zhuǎn)換為0怎么辦?

          這是在單獨的JavaScript條件下進行的: 真值和虛值 。除了true以外,JavaScript 將大部分有值的視為真值,除了少數(shù)值。例如,0,-0,""被視為虛值。由于空數(shù)組不被認為是虛值,當在條件中檢查它時,它將作為真值執(zhí)行。(這里不會發(fā)生類型轉(zhuǎn)換,空數(shù)組保留為數(shù)組,這是類型轉(zhuǎn)換不一致的另一個例子。)

          總結(jié)

          JavaScript作為一種松散類型語言,執(zhí)行隱式類型轉(zhuǎn)換。這會導致不一致和意想不到的結(jié)果。因此,我們應(yīng)該在任何時候都避免這種類型轉(zhuǎn)換。如果不確定值的類型,可以使用typeof檢查。檢查類型可以讓我們更好地理解應(yīng)該如何進行轉(zhuǎn)換。

          ~完,我是刷碗智,我要去刷碗了,骨的白~


          作者:Viduni Wickramarachchi 譯者:前端小智 來源:stackabuse

          原文:https://blog.bitc.io/how-to-avoid-javascript-type-conversions-29e1258f37d8


          主站蜘蛛池模板: 国产精品一区二区av| 久久精品日韩一区国产二区| 3D动漫精品啪啪一区二区下载| 久久无码AV一区二区三区| 亚洲色一区二区三区四区 | 无码精品尤物一区二区三区| 无码人妻一区二区三区精品视频| 国产精品高清视亚洲一区二区| 精品一区二区在线观看| 一区免费在线观看| 国产一区二区三区在线看片| 成人精品一区二区电影 | 国精品无码一区二区三区在线蜜臀 | 日本免费一区二区在线观看| 久久国产视频一区| 国产成人精品无码一区二区三区 | 风流老熟女一区二区三区| 国产精品久久久久一区二区三区 | 精品一区二区三区免费毛片| 国产精品av一区二区三区不卡蜜| 麻豆AV一区二区三区| 激情内射亚洲一区二区三区爱妻| 久久精品黄AA片一区二区三区| 日本不卡一区二区三区| 午夜福利一区二区三区高清视频 | 日韩精品无码一区二区三区AV| 中文字幕在线一区二区三区| 三上悠亚国产精品一区| 日韩电影一区二区三区| 日韩亚洲AV无码一区二区不卡| 高清一区二区三区免费视频| 色窝窝无码一区二区三区成人网站| 国产在线视频一区| 亚州日本乱码一区二区三区| 无码国产精品一区二区免费vr| 中文激情在线一区二区| 五十路熟女人妻一区二区| 日本在线视频一区二区三区| 一区二区中文字幕在线观看| 中文字幕日韩人妻不卡一区| 无码av免费一区二区三区|