【JavaScript】《JavaScript高級程序設計 (第4版) 》筆記-附錄B-嚴格模式

附錄B、嚴格模式
  1. 嚴格模式

    • ECMAScript 5 首次引入嚴格模式的概念。嚴格模式用于選擇以更嚴格的條件檢查 JavaScript 代碼錯誤,可以應用到全局,也可以應用到函數內部。嚴格模式的好處是可以提早發現錯誤,因此可以捕獲某些 ECMAScript 問題導致的編程錯誤。
    • 理解嚴格模式的規則非常重要,因為未來的 ECMAScript 會逐步強制全局使用嚴格模式。嚴格模式已得到所有主流瀏覽器支持。
  2. 選擇使用

    • 要選擇使用嚴格模式,需要使用嚴格模式編譯指示(pragma),即一個不賦值給任何變量的字符串:
      "use strict";
      
    • 這樣一個即使在 ECMAScript 3 中也有效的字符串,可以兼容不支持嚴格模式的 JavaScript 引擎。支持嚴格模式的引擎會啟用嚴格模式,而不支持的引擎則會將這個編譯指示當成一個未賦值的字符串字面量。
    • 如果把這個編譯指示應用到全局作用域,即函數外部,則整個腳本都會按照嚴格模式來解析。這意味著在最終會與其他腳本拼接為一個文件的腳本中添加了編譯指示,會將該文件中的所有 JavaScript 置于嚴格模式之下。
    • 也可以像下面這樣只在一個函數內部開啟嚴格模式:
      function doSomething() { "use strict"; // 其他代碼
      }
      
    • 如果你不能控制頁面中的所有腳本,那么建議只在經過測試的特定函數中啟用嚴格模式。
  3. 變量

    • 嚴格模式下如何創建變量及何時會創建變量都會發生變化。第一個變化是不允許意外創建全局變量。在非嚴格模式下,以下代碼可以創建全局變量:
      // 變量未聲明
      // 非嚴格模式:創建全局變量
      // 嚴格模式:拋出 ReferenceError 
      message = "Hello world!";
      
    • 雖然這里的 message 沒有前置 let 關鍵字,也沒有明確定義為全局對象的屬性,但仍然會自動創建為全局變量。在嚴格模式下,給未聲明的變量賦值會在執行代碼時拋出 ReferenceError。
    • 相關的另一個變化是無法在變量上調用 delete。在非嚴格模式下允許這樣,但可能會靜默失敗(返回 false)。在嚴格模式下,嘗試刪除變量會導致錯誤:
      // 刪除變量
      // 非嚴格模式:靜默失敗
      // 嚴格模式:拋出 ReferenceError 
      let color = "red"; 
      delete color;
      
    • 嚴格模式也對變量名增加了限制。具體來說,不允許變量名為 implements、interface、let、package、private、protected、public、static 和 yield。這些是目前的保留字,可能在將來的 ECMAScript 版本中用到。如果在嚴格模式下使用這些名稱作為變量名,則會導致語法錯誤。
  4. 對象

    • 在嚴格模式下操作對象比在非嚴格模式下更容易拋出錯誤。嚴格模式傾向于在非嚴格模式下會靜默失敗的情況下拋出錯誤,增加了開發中提前發現錯誤的可能性。
    • 首先,以下幾種情況下試圖操縱對象屬性會引發錯誤。
      • 給只讀屬性賦值會拋出 TypeError。
      • 在不可配置屬性上使用 delete 會拋出 TypeError。
      • 給不存在的對象添加屬性會拋出 TypeError。
    • 另外,與對象相關的限制也涉及通過對象字面量聲明它們。在使用對象字面量時,屬性名必須唯一。例如:
      // 兩個屬性重名
      // 非嚴格模式:沒有錯誤,第二個屬性生效
      // 嚴格模式:拋出 SyntaxError 
      let person = { name: "Nicholas", name: "Greg" 
      };
      
    • 這里的對象字面量 person 有兩個叫作 name 的屬性。第二個屬性在非嚴格模式下是最終的屬性。但在嚴格模式下,這樣寫是語法錯誤。
    • 注意,ECMAScript 6 刪除了對重名屬性的這個限制,即在嚴格模式下重復的對象字面量屬性鍵不會拋出錯誤。
  5. 函數

    • 首先,嚴格模式要求命名函數參數必須唯一。看下面的例子:
      // 命名參數重名
      // 非嚴格模式:沒有錯誤,只有第二個參數有效
      // 嚴格模式:拋出 SyntaxError 
      function sum (num, num){ // 函數代碼
      }
      
    • 在非嚴格模式下,這個函數聲明不會拋出錯誤。這樣可以通過名稱訪問第二個 num,但只能通過arguments 訪問第一個參數。
    • arguments 對象在嚴格模式下也有一些變化。在非嚴格模式下,修改命名參數也會修改 arguments對象中的值。而在嚴格模式下,命名參數和 arguments 是相互獨立的。例如:
      // 修改命名參數的值
      // 非嚴格模式:arguments 會反映變化
      // 嚴格模式:arguments 不會反映變化
      function showValue(value){ value = "Foo"; alert(value); // "Foo" alert(arguments[0]); // 非嚴格模式:"Foo" // 嚴格模式:"Hi" 
      } 
      showValue("Hi");
      
    • 在這個例子中,函數 showValue()有一個命名參數 value。調用這個函數時給它傳入參數"Hi",該值會賦給value。在函數內部,value被修改為"Foo"。在非嚴格模式下,這樣也會修改arguments[0]的值,但在嚴格模式下則不會。
    • 另一個變化是去掉了 arguments.callee 和 arguments.caller。在非嚴格模式下,它們分別引用函數本身和調用函數。在嚴格模式下,訪問這兩個屬性中的任何一個都會拋出 TypeError。例如:
      // 訪問 arguments.callee 
      // 非嚴格模式:沒問題
      // 嚴格模式:拋出 TypeError 
      function factorial(num){ if (num <= 1) { return 1; } else { return num * arguments.callee(num-1) } 
      } 
      let result = factorial(5);
      
    • 類似地,讀或寫函數的 caller 或 callee 屬性也會拋出 TypeError。因此對這個例子而言,訪問factorial.caller 和 factorial.callee 也會拋出錯誤。
    • 另外,與變量一樣,嚴格模式也限制了函數的命名,不允許函數名為 implements、interface、let、package、private、protected、public、static 和 yield。
    • 關于函數的最后一個變化是不允許函數聲明,除非它們位于腳本或函數的頂級。這意味著在 if 語句中聲明的函數現在是個語法錯誤:
      // 在 if 語句中聲明函數
      // 非嚴格模式:函數提升至 if 語句外部
      // 嚴格模式:拋出 SyntaxError 
      if (true){ function doSomething(){ // ... } 
      }
      
  6. 函數參數

    • ES6 增加了剩余操作符、解構操作符和默認參數,為函數組織、結構和定義參數提供了強大的支持。ECMAScript 7 增加了一條限制,要求使用任何上述先進參數特性的函數內部都不能使用嚴格模式,否則會拋出錯誤。不過,全局嚴格模式還是允許的。
      // 可以
      function foo(a, b, c) { "use strict"; 
      } 
      // 不可以
      function bar(a, b, c='d') { "use strict"; 
      } 
      // 不可以
      function baz({a, b, c}) { "use strict"; 
      } 
      // 不可以
      function qux(a, b, ...c) { "use strict"; 
      }
      
    • ES6 增加的這些新特性期待參數與函數體在相同模式下進行解析。如果允許編譯指示"use strict"出現在函數體內,JavaScript 解析器就需要在解析函數參數之前先檢查函數體內是否存在這個編譯指示,而這會帶來很多問題。為此,ES7 規范增加了這個約定,目的是讓解析器在解析函數之前就確切知道該使用什么模式。
  7. eval()

    • eval()函數在嚴格模式下也有變化。最大的變化是 eval()不會再在包含上下文中創建變量或函數。例如:
      // 使用 eval()創建變量
      // 非嚴格模式:警告框顯示 10 
      // 嚴格模式:調用 alert(x)時拋出 ReferenceError 
      function doSomething(){ eval("let x = 10"); alert(x); 
      }
      
    • 以上代碼在非嚴格模式下運行時,會在 doSomething()函數內部創建局部變量 x,然后 alert()會顯示這個變量的值。在嚴格模式下,調用 eval()不會在 doSomething()中創建變量 x,由于 x 沒有聲明,alert()會拋出 ReferenceError。
    • 變量和函數可以在 eval()中聲明,但它們會位于代碼執行期間的一個特殊的作用域里,代碼執行完畢就會銷毀。因此,以下代碼就不會出錯:
      "use strict"; 
      let result = eval("let x = 10, y = 11; x + y"); 
      alert(result); // 21
      
    • 這里在 eval()中聲明了變量 x 和 y,將它們相加后返回得到的結果。變量 result 會包含 x 和 y相加的結果 21,雖然 x 和 y 在調用 alert()時已經不存在了,但不影響結果的顯示。
  8. eval 與 arguments

    • 嚴格模式明確不允許使用 eval 和 arguments 作為標識符和操作它們的值。例如:
      // 將 eval 和 arguments 重新定義為變量
      // 非嚴格模式:可以,沒有錯誤
      // 嚴格模式:拋出 SyntaxError 
      let eval = 10; 
      let arguments = "Hello world!";
      
    • 在非嚴格模式下,可以重寫 eval 和 arguments。在嚴格模式下,這樣會導致語法錯誤。不能用它們作為標識符,這意味著下面這些情況都會拋出語法錯誤:
      • 使用 let 聲明;
      • 賦予其他值;
      • 修改其包含的值,如使用++;
      • 用作函數名;
      • 用作函數參數名;
      • 在 try/catch 語句中用作異常名稱。
  9. this 強制轉型

    • JavaScript 中最大的一個安全問題,也是最令人困惑的一個問題,就是在某些情況下 this 的值是如何確定的。使用函數的 apply()或 call()方法時,在非嚴格模式下 null 或 undefined 值會被強制轉型為全局對象。在嚴格模式下,則始終以指定值作為函數 this 的值,無論指定的是什么值。例如:
      // 訪問屬性
      // 非嚴格模式:訪問全局屬性
      // 嚴格模式:拋出錯誤,因為 this 值為 null 
      let color = "red"; 
      function displayColor() { alert(this.color); 
      } 
      displayColor.call(null);
      
    • 這里在調用 displayColor.call()時傳入 null 作為 this 的值,在非嚴格模式下該函數的 this值是全局對象。結果會顯示"red"。在嚴格模式下,該函數的 this 值是 null,因此在訪問 null 的屬性時會拋出錯誤。
    • 通常,函數會將其 this 的值轉型為一種對象類型,這種行為經常被稱為“裝箱”(boxing)。這意味著原始值會轉型為它們的包裝對象類型。
      function foo() { console.log(this); 
      } 
      foo.call(); // Window {} 
      foo.call(2); // Number {2}
      
    • 在嚴格模式下執行以上代碼時,this 的值不會再“裝箱”:
      function foo() { "use strict"; console.log(this);
      } 
      foo.call(); // undefined 
      foo.call(2); // 2
      
  10. 類與模塊

    • 類和模塊都是 ECMAScript 6 新增的代碼容器特性。在之前的 ECMAScript 版本中沒有類和模塊這兩個概念,因此不用考慮從語法上兼容之前的 ECMAScript 版本。為此,TC39 委員會決定在 ES6 類和模塊中定義的所有代碼默認都處于嚴格模式。
    • 對于類,這包括類聲明和類表達式,構造函數、實例方法、靜態方法、獲取方法和設置方法都在嚴格模式下。對于模塊,所有在其內部定義的代碼都處于嚴格模式。
  11. 其他變化

    • 嚴格模式下還有其他一些需要注意的變化。首先是消除 with 語句。with 語句改變了標識符解析時的方式,嚴格模式下為簡單起見已去掉了這個語法。在嚴格模式下使用 with 會導致語法錯誤:
      // 使用 with 語句
      // 非嚴格模式:允許
      // 嚴格模式:拋出 SyntaxError 
      with(location) { alert(href); 
      } 
      
    • 嚴格模式也從 JavaScript 中去掉了八進制字面量。八進制字面量以前導 0 開始,一直以來是很多錯誤的源頭。在嚴格模式下使用八進制字面量被認為是無效語法:
      // 使用八進制字面量
      // 非嚴格模式:值為 8 
      // 嚴格模式:拋出 SyntaxError 
      let value = 010;
      
    • ECMAScript 5修改了非嚴格模式下的parseInt(),將八進制字面量當作帶前導0的十進制字面量。例如:
      // 在 parseInt()中使用八進制字面量
      // 非嚴格模式:值為 8 
      // 嚴格模式:值為 10 
      let value = parseInt("010");
      

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72469.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72469.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72469.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

藍橋試題:混境之地(記憶化搜索)

一、問題描述 小藍有一天誤入了一個混境之地。 好消息是&#xff1a;他誤打誤撞拿到了一張地圖&#xff0c;并從中獲取到以下信息&#xff1a; 混境之地是一個n?m 大小的矩陣&#xff0c;其中第 i 行第 j 列的的點 h i j? 表示第 i 行第 j 列的高度。他現在所在位置的坐標…

CC++鏈接數據庫(MySQL)超級詳細指南

C/C鏈接數據庫&#xff08;MySQL&#xff09;超級詳細指南 在C/C編程中&#xff0c;與數據庫進行交互是一項常見的任務。MySQL作為一個廣泛使用的開源關系型數據庫管理系統&#xff0c;提供了豐富的API供C/C開發者使用。本文將詳細介紹如何在C/C程序中鏈接MySQL數據庫&#xf…

基于EM期望最大化算法的GMM參數估計與三維數據分類系統python源碼

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 4.1 EM算法 E步:期望步 M步:最大化步 4.2 GMM模型 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 程序運行配置環境&#xff1a; 人工智能算法…

制服小程序的“滑手”:禁用頁面左右滑動全攻略

哈哈&#xff0c;看來你已經很聰明地發現了小程序中左右滑動的“頑皮”行為&#xff01;&#x1f604; 沒錯&#xff0c;我們可以通過設置 disableScroll 屬性來“管教”它&#xff0c;同時結合 CSS 樣式讓頁面既禁得住橫向“亂跑”&#xff0c;又能順暢地上下滾動。你的方案已…

docker學習筆記(1)從安裝docker到使用Portainer部署容器

docker學習筆記第一課 先交代背景 docker宿主機系統&#xff1a;阿里云ubuntu22.04 開發機系統&#xff1a;win11 docker鏡像倉庫&#xff1a;阿里云&#xff0c;此阿里云與宿主機系統沒有關系&#xff0c;是阿里云提供的一個免費的docker倉庫 代碼托管平臺&#xff1a;github&…

stable-diffusion-webui 加載模型文件

背景 stable-diffusion-webui 安裝完畢后&#xff0c;默認的模型生成的效果圖并不理想&#xff0c;可以根據具體需求加載指定的模型文件。國內 modelscope 下載速度較快&#xff0c;以該站為例進行介紹 操作步驟 找到指定的模型文件 在 https://modelscope.cn/models 中查找…

kotlin高級用法總結

Kotlin 是一門功能強大且靈活的編程語言&#xff0c;除了基礎語法外&#xff0c;它還提供了許多高級特性&#xff0c;可以幫助你編寫更簡潔、高效和可維護的代碼。以下是 Kotlin 的一些高級用法&#xff0c;涵蓋了協程、擴展函數、屬性委托、內聯類、反射等內容。 協程&#x…

Linux網絡 NAT、代理服務、內網穿透

NAT 技術 IPv4 協議中存在 IP 地址數量不充足的問題&#xff0c;而 NAT 技術是當前解決 IP 地址不夠用的主要手段 , 是路由器的一個重要功能。NAT 能夠將私有 IP 對外通信時轉為全局 IP&#xff0c;也就是就是一種將私有 IP 和全局 IP 相互轉化的技術方法。 這可以讓很多學…

世界模型在塑造自動駕駛中的作用:綜述

25年2月來自華中理工和百度的論文“”The Role of World Models in Shaping Autonomous Driving: A Comprehensive Survey“。 駕駛世界模型 (DWM) 專注于預測駕駛過程中的場景演變&#xff0c;已成為實現自動駕駛一個有前途的范例。這些方法使自動駕駛系統能夠更好地感知、理…

全向廣播揚聲器在油氣田中的關鍵應用 全方位守護安全

油氣田作為高風險作業場所&#xff0c;安全生產始終是重中之重。在緊急情況下&#xff0c;如何快速、有效地傳達信息&#xff0c;確保人員安全撤離&#xff0c;是油氣田安全管理的關鍵環節。全向廣播揚聲器憑借其全方位覆蓋、高音質輸出和強大的環境適應性&#xff0c;成為油氣…

【AI大模型】AI賦能,使用DeepSeek 高效制作PPT實戰詳解

目錄 一、前言 二、傳統 PPT 制作問題 2.1 傳統方式制作 PPT 2.2 AI 大模型輔助制作 PPT 2.3 適用場景對比分析 2.4 最佳實踐與推薦 三、DeepSeek Kimi 高效制作PPT操作實踐 3.1 Kimi 簡介 3.2 DeepSeek Kimi 制作PPT優勢 3.2.1 DeepSeek 優勢 3.2.2 Kimi 制作PPT優…

【51單片機】程序實驗13.串口通信

主要參考學習資料&#xff1a;B站【普中官方】51單片機手把手教學視頻 開發資料下載鏈接&#xff1a;http://www.prechin.cn/gongsixinwen/208.html 前置知識&#xff1a;C語言 單片機套裝&#xff1a;普中STC51單片機開發板A4標準版套餐7 目錄 通信的基本概念串行通信與并行通…

論文閱讀筆記:ArcFace: Additive Angular Margin Loss for Deep Face Recognition

論文閱讀筆記&#xff1a;ArcFace: Additive Angular Margin Loss for Deep Face Recognition 1 背景2 創新點3 方法4 模塊4.1 Softmax4.2 權重歸一化4.3 乘性角度間隔4.4 特征歸一化4.5 加性余弦間隔4.6 加性角度間隔4.7 二值化情況下的比較4.8 目標Logit分析 5 效果5.1 消融實…

代碼隨想錄算法訓練營 | 圖論 | DFS

98. 所有可達路徑// DFS #include <bits/stdc.h> using namespace std;vector<vector<int>> result; vector<int> path;void dfs(const vector<list<int>> &graph, int i, int target) {if (i target) {result.push_back(path);retu…

GPPT: Graph Pre-training and Prompt Tuning to Generalize Graph Neural Networks

GPPT: Graph Pre-training and Prompt Tuning to Generalize Graph Neural Networks KDD22 推薦指數&#xff1a;#paper/??#? 動機 本文探討了圖神經網絡&#xff08;GNN&#xff09;在遷移學習中“預訓練-微調”框架的局限性及改進方向。現有方法通過預訓練&#xff08…

迷你世界腳本方塊接口:Block

方塊接口&#xff1a;Block 彼得兔 更新時間: 2024-08-27 11:04:56 具體函數名及描述如下&#xff1a; 序號 函數名 函數描述 1 isSolidBlock(...) 是否是固體方塊 2 isLiquidBlock(...) 是否是液體方塊 3 isAirBlock(...) 是否是氣體方塊 4 getBl…

Windows下git疑難:有文件無法被跟蹤

Windows下git疑難&#xff1a;有文件無法被跟蹤 最近在寫一個c# WinFrom程序&#xff0c; 奇怪的是&#xff0c;frmMain.cs這個文件一直無法被跟蹤 研究了很久&#xff0c; 參考這一篇 https://blog.csdn.net/m0_37315653/article/details/83064810 git rm --cached ./ -r 之…

Live2d官方項目運行

Live2d官方項目運行 1-參考網址 教程網址&#xff1a;https://blog.csdn.net/qq_39123467/article/details/131735085live2d官方地址&#xff1a;https://live2d.com/cubism-sdk/download/ 2-上手實踐 1&#xff09;先打開官方項目-全部路徑打開2&#xff09;cd /CubismSdkFo…

BUU43 [BJDCTF2020]The mystery of ip 1

前置知識&#xff1a; X - Forwarded - For注入 X - Forwarded - For&#xff08;XFF&#xff09;是一個 HTTP 頭字段&#xff0c;用于記錄客戶端的真實 IP 地址。當客戶端請求經過代理服務器時&#xff0c;代理服務器會將客戶端的 IP 地址添加到 X - Forwarded - For 頭中。…

張岳教授:語言模型推理與泛化研究 | ICLR 2025 特邀報告與團隊專場

點擊藍字 關注我們 AI TIME歡迎每一位AI愛好者的加入&#xff01; AITIME 01 ICLR 2025預講會特邀報告 AITIME 02 ICLR 2025預講會西湖大學張岳老師實驗室專場 01 AI生成文本的自動化檢測 Glimpse: Enabling White-Box Methods to Use Proprietary Models for Zero-Shot LLM-Ge…