js嚴(yán)格模式和非嚴(yán)格模式區(qū)別小結(jié)
好的,這是一個(gè)非常基礎(chǔ)且重要的概念。我們來(lái)詳細(xì)解析一下 JavaScript 中的嚴(yán)格模式(Strict Mode)和非嚴(yán)格模式(Sloppy Mode)。
可以把它想象成參加一場(chǎng)考試:
- 非嚴(yán)格模式:就像是開(kāi)卷、不計(jì)時(shí)的隨堂測(cè)驗(yàn),規(guī)則很寬松,寫(xiě)得不那么標(biāo)準(zhǔn)也能得分,老師會(huì)盡量“猜測(cè)”你的意圖。
- 嚴(yán)格模式:就像是正式的閉卷大考,有嚴(yán)格的規(guī)范,任何不符合規(guī)則的寫(xiě)法都會(huì)被立刻標(biāo)記為錯(cuò)誤,不留任何情面。
1. 什么是嚴(yán)格模式?
嚴(yán)格模式 (Strict Mode) 是在 ECMAScript 5 (ES5) 中引入的一種選擇性加入(opt-in)的機(jī)制,它為 JavaScript 代碼選擇了一種更嚴(yán)格、更受限的語(yǔ)法和錯(cuò)誤處理規(guī)則。
它的本質(zhì)是讓 JavaScript 引擎以一種更“嚴(yán)謹(jǐn)”的方式來(lái)解析和執(zhí)行你的代碼,從而提高代碼的健壯性和安全性。
非嚴(yán)格模式 (Sloppy Mode) 則是 JavaScript 默認(rèn)的、向后兼容的、更“寬容”的模式。
2. 為什么需要嚴(yán)格模式?
JavaScript 最初被設(shè)計(jì)為一門(mén)非常寬容的語(yǔ)言,為了讓網(wǎng)頁(yè)在各種意外情況下都能勉強(qiáng)運(yùn)行(而不是直接崩潰)。但這種寬容性也導(dǎo)致了一些問(wèn)題:
- 靜默錯(cuò)誤 (Silent Errors):一些本該是錯(cuò)誤的操作,在非嚴(yán)格模式下不會(huì)報(bào)錯(cuò),只會(huì)靜默失敗,這使得調(diào)試變得異常困難。
- 不安全的行為: 某些語(yǔ)法可能存在安全隱患或?qū)е乱馔獾娜肿兞课廴尽?/li>
- 阻礙引擎優(yōu)化: 一些“壞語(yǔ)法”讓 JavaScript 引擎難以對(duì)代碼進(jìn)行性能優(yōu)化。
- 為未來(lái)做準(zhǔn)備: 禁止一些未來(lái)可能被用作新關(guān)鍵字的保留字。
嚴(yán)格模式的誕生就是為了解決這些歷史遺留問(wèn)題。
3. 如何開(kāi)啟嚴(yán)格模式?
開(kāi)啟嚴(yán)格模式非常簡(jiǎn)單,只需在代碼的特定位置添加一個(gè)字符串字面量:
"use strict";
根據(jù)你放置的位置,它的作用域也不同:
全局嚴(yán)格模式: 將 "use strict";
放在腳本文件的最頂部。
// my-script.js "use strict"; // 整個(gè)文件都將以嚴(yán)格模式運(yùn)行 let x = 10; // ...
函數(shù)內(nèi)嚴(yán)格模式: 將 "use strict";
放在函數(shù)體的最頂部。
function myStrictFunction() { "use strict"; // 只有這個(gè)函數(shù)內(nèi)部是以嚴(yán)格模式運(yùn)行的 let y = 20; // ... }
一個(gè)非常重要的現(xiàn)代知識(shí)點(diǎn):
在 ES6 模塊 (import/export) 和 class 的代碼塊中,嚴(yán)格模式是默認(rèn)開(kāi)啟的,你無(wú)需手動(dòng)添加 "use strict";。這就是為什么在現(xiàn)代前端框架(如 React, Vue)的開(kāi)發(fā)中,你很少看到這行代碼,因?yàn)槟銓?xiě)的代碼基本上都已經(jīng)是運(yùn)行在嚴(yán)格模式下的模塊了。
4. 嚴(yán)格模式與非嚴(yán)格模式的主要區(qū)別
下面是一些最直觀和重要的區(qū)別,通過(guò)代碼對(duì)比會(huì)非常清晰:
a. 禁止意外創(chuàng)建全局變量
這是最經(jīng)典的區(qū)別。
非嚴(yán)格模式:
function createGlobal() { mistake = "I am a global variable!"; // 忘記寫(xiě) let/const/var } createGlobal(); console.log(window.mistake); // "I am a global variable!" (在瀏覽器中) // 變量泄漏到了全局作用域,這是一個(gè)非常危險(xiǎn)的副作用。
嚴(yán)格模式:
"use strict"; function createGlobal() { mistake = "This will cause an error"; } // createGlobal(); // 這一行會(huì)直接拋出 ReferenceError,程序會(huì)中斷
結(jié)論:嚴(yán)格模式將一個(gè)常見(jiàn)的“靜默錯(cuò)誤”變成了“拋出錯(cuò)誤”,讓你能立刻發(fā)現(xiàn)問(wèn)題。
b. 禁止對(duì)只讀屬性或不可擴(kuò)展對(duì)象進(jìn)行修改
非嚴(yán)格模式:
const obj = {}; Object.defineProperty(obj, 'readOnly', { value: 10, writable: false }); obj.readOnly = 20; // 嘗試修改只讀屬性 console.log(obj.readOnly); // 10 (修改靜默失敗,不會(huì)報(bào)錯(cuò))
嚴(yán)格模式:
"use strict"; const obj = {}; Object.defineProperty(obj, 'readOnly', { value: 10, writable: false }); // obj.readOnly = 20; // 這一行會(huì)拋出 TypeError
結(jié)論: 嚴(yán)格模式同樣將靜默失敗的操作變成了明確的錯(cuò)誤。
c.this的指向不同
我們?cè)谥暗木毩?xí)中已經(jīng)遇到過(guò)。
非嚴(yán)格模式:
function showThis() { console.log(this); } showThis(); // 在瀏覽器中,會(huì)輸出全局的 window 對(duì)象
嚴(yán)格模式:
"use strict"; function showThis() { console.log(this); } showThis(); // 輸出 undefined
結(jié)論: 嚴(yán)格模式下的 this
行為更安全,避免了意外地污染全局對(duì)象。
d. 禁止重復(fù)的參數(shù)名
非嚴(yán)格模式:
function sum(a, a, b) { // 不會(huì)報(bào)錯(cuò) return a + a + b; // 實(shí)際上是第二個(gè) a 生效 } console.log(sum(1, 2, 3)); // 2 + 2 + 3 = 7
嚴(yán)格模式:
"use strict"; // function sum(a, a, b) { // 這一行在代碼解析階段就會(huì)拋出 SyntaxError // return a + b; // }
結(jié)論: 嚴(yán)格模式在語(yǔ)法層面就杜絕了這種不合理的代碼。
總結(jié)與建議
特性 | 非嚴(yán)格模式 (Sloppy Mode) | 嚴(yán)格模式 (Strict Mode) |
---|---|---|
意外全局變量 | 允許,靜默創(chuàng)建 | 禁止,拋出 ReferenceError |
修改只讀屬性 | 靜默失敗 | 禁止,拋出 TypeError |
全局函數(shù)this | 指向全局對(duì)象 (window) | undefined |
重復(fù)參數(shù)名 | 允許(最后一個(gè)生效) | 禁止,拋出 SyntaxError |
最終建議:始終使用嚴(yán)格模式!
在今天,你沒(méi)有任何理由不使用嚴(yán)格模式。它能幫你寫(xiě)出更健壯、更安全、更規(guī)范的代碼,并且能讓你避免很多難以調(diào)試的“幽靈bug”。
鑒于現(xiàn)代 JavaScript 的模塊和類已經(jīng)默認(rèn)開(kāi)啟了嚴(yán)格模式,將 "use strict";
放在所有非模塊化的老腳本的頂部,應(yīng)該成為你的一個(gè)標(biāo)準(zhǔn)習(xí)慣。
到此這篇關(guān)于js嚴(yán)格模式和非嚴(yán)格模式區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)js 嚴(yán)格模式 非嚴(yán)格模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript基于replace+正則實(shí)現(xiàn)ES6的字符串模版功能
這篇文章主要介紹了JavaScript基于replace+正則實(shí)現(xiàn)ES6的字符串模版功能,結(jié)合實(shí)例形式分析了replace結(jié)合正則實(shí)現(xiàn)ES6字符串模板功能的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04layui checkbox默認(rèn)選中,獲取選中值,清空所有選中項(xiàng)的例子
今天小編就為大家分享一篇layui checkbox默認(rèn)選中,獲取選中值,清空所有選中項(xiàng)的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JavaScript eval() 函數(shù)介紹及應(yīng)用示例
eval(String) 函數(shù)可計(jì)算某個(gè)字符串,并執(zhí)行其中的的 JavaScript 代碼,該方法只接受原始字符串作為參數(shù)2014-07-07關(guān)于IE中g(shù)etElementsByClassName不能用的問(wèn)題解決方法
今天使用getElementsByClassName寫(xiě)了段小程序,在IE6、8中測(cè)試的時(shí)候就出現(xiàn)問(wèn)題了,瀏覽器報(bào)錯(cuò),經(jīng)搜索找到了一個(gè)比較好的方法,是個(gè)老外寫(xiě)的一個(gè)方法2013-08-08詳解利用exif.js解決ios手機(jī)上傳豎拍照片旋轉(zhuǎn)90度問(wèn)題
這篇文章主要介紹了詳解利用exif.js解決ios手機(jī)上傳豎拍照片旋轉(zhuǎn)90度問(wèn)題,有需要的朋友可以了解一下。2016-11-11基于JavaScript實(shí)現(xiàn)年份數(shù)字拼圖效果
時(shí)光荏苒,2022年又要收尾了,公司的年會(huì)是不是都安排上了?前幾天看到一個(gè)年會(huì)抽獎(jiǎng)系統(tǒng),功能十分的強(qiáng)大,其中有一個(gè)年份數(shù)字的拼圖效果深深的吸引了哥,決定用JS實(shí)現(xiàn)一下該效果,需要的可以參考一下2022-12-12js 原生判斷內(nèi)容區(qū)域是否滾動(dòng)到底部的實(shí)例代碼
下面筆者就為大家分享一篇js 原生判斷內(nèi)容區(qū)域是否滾動(dòng)到底部的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2017-11-11JS實(shí)現(xiàn)點(diǎn)擊循環(huán)切換顯示內(nèi)容的方法
這篇文章主要介紹了JS實(shí)現(xiàn)點(diǎn)擊循環(huán)切換顯示內(nèi)容的方法,涉及javascript鼠標(biāo)事件響應(yīng)及頁(yè)面元素的獲取、屬性設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2017-10-1024個(gè)實(shí)用JavaScript?開(kāi)發(fā)技巧
這篇文章主要給大家分享了24個(gè)實(shí)用JavaScript?的開(kāi)發(fā)技巧,文章圍繞JavaScript?的開(kāi)發(fā)技巧講解展開(kāi)全文,具有一定的參考價(jià)值,需要的朋友可以參考一下,希望對(duì)你有所幫助2021-12-12