搜尋
首頁web前端js教程JS中強烈打字的語言借用技術

Borrowing Techniques from Strongly Typed Languages in JS

本文探討如何在 JavaScript 代碼中運用強類型語言的技巧。這些技巧不僅能減少代碼錯誤,還能縮減代碼量。雖然本文以 JavaScript 為例,但這些技巧也適用於大多數弱類型語言。

關鍵要點:

  • 在 JavaScript 中應用強類型語言的技巧可以減少 bug 並縮減代碼量。
  • “一致類型規則”(規定所有值只有一種類型)可以應用於 JavaScript 以提高代碼質量和可讀性。
  • 應在模塊邊緣執行類型檢查和類型轉換,以防止隱式類型強制轉換導致的 bug 並簡化代碼。
  • 應仔細考慮在 JavaScript 中使用“null”和“undefined”,尤其是在處理對象和數組等引用類型時。
  • TypeScript 是一個推薦用於在 JavaScript 中強制執行更強類型語義的工具,它具有早期錯誤檢測和更清晰的代碼文檔等優點。

JavaScript 類型系統

首先快速回顧一下 JavaScript 數據類型系統的工作原理。 JavaScript 將其值分為兩類:

  • 原始類型,例如 String、Number 和 Boolean。將原始類型賦值給變量時,始終會創建一個新值,它是所賦值值的副本。
  • 引用類型,例如 Object 和 Array。賦值引用類型始終複製相同的引用。為了闡明這一點,讓我們來看下面的代碼示例:
var a = [];
var b = a;

a.push('Hello');

當我們更改 a 時,變量 b 也會發生變化,因為它們都引用同一個數組。所有引用類型的工作方式都是如此。 JavaScript 不會強制執行任何類型,這意味著任何變量都可以在任何時候保存任何數據類型。本文其餘部分將討論此方法的缺點,以及如何應用強制執行類型的語言中的簡單技巧來編寫更好的 JavaScript 代碼。

引入一致類型規則

一致類型規則在理論上很簡單:所有值都應該只有一種類型。強類型語言在編譯器級別強制執行此規則,它們不允許您隨意混合和匹配類型。弱類型賦予我們很大的自由度。一個常見的例子是將數字連接到字符串中。您不需要執行像在 C 等語言中那樣繁瑣的類型轉換。別擔心,我不會告訴您放棄所有便利。一致類型規則只需要您注意變量和函數的行為方式,這樣您的代碼就會得到改進。

變量中的類型

首先,讓我們看看該規則如何應用於變量。它非常簡單:您的變量應該始終只有一種類型。

var a = [];
var b = a;

a.push('Hello');

上面的示例顯示了問題所在。此規則要求我們假裝此示例中的最後一行代碼會拋出錯誤,因為當我們第一次定義變量 text 時,我們賦予它字符串類型的 value,現在我們正在為其賦值一個數字。一致類型規則意味著我們不允許這樣更改變量的類型。當您的變量一致時,更容易推斷您的代碼。它尤其有助於更長的函數,在這些函數中,很容易忽略變量的來源。當在不遵守此規則的代碼庫中工作時,我意外地導致了許多錯誤,因為我看到聲明了一個變量,然後假設它會保持相同的類型——因為讓我們面對現實,這有意義,不是嗎?通常沒有理由將不同的類型分配給同一個變量。

函數參數中的類型

相同的規則也適用於此。函數的參數也應該保持一致。一個錯誤的例子:

var text = 'Hello types';

// 错误!不要这样做!
text = 1;

這裡有什麼問題?通常認為,根據類型檢查來分支邏輯是不好的做法。對此有一些例外,但通常更好的選擇是使用多態性。您應該努力確保函數參數也只有一種類型。如果您忘記考慮不同的類型,它會減少出現問題的可能性,並使代碼更簡單,因為您不必編寫代碼來處理所有不同類型的案例。編寫 sum 函數的更好方法如下:

function sum(a, b) {
  if (typeof a === 'string') {
    a = 1;
  }

  return a + b;
}

然後,您在調用代碼中而不是在函數中處理類型檢查。從上面可以看出,該函數現在簡單多了。即使我們必須將類型檢查移動到其他地方,我們越早在代碼中執行它們,效果就越好。我們將在本文後面討論類型檢查和 typeof 的使用,包括如果使用不當,類型檢查如何輕鬆級聯。

函數返回值中的類型

這與其他兩個相關:您的函數應該始終返回相同類型的 value。我們可以在這裡舉 AngularJS 的一個例子。 AngularJS 提供了一個將文本轉換為小寫的函數,稱為 angular.lowercase。還有一個標準函數,String.prototype.toLowerCase。我們可以比較它們的行為來更好地理解規則的這一部分:

function sum(a, b) {
  return a + b;
}

變量 a 將包含您期望的內容:“hello types”。但是,b 將包含什麼?它將是一個空字符串嗎?函數會拋出異常嗎?或者它可能只是 null?在這種情況下,b 的 value 為 null。請注意,立即很難猜測結果是什麼——我們一開始就有三種可能的結果。對於 Angular 函數,對於非字符串值,它將始終返回輸入。現在,讓我們看看內置函數的行為:

var a = [];
var b = a;

a.push('Hello');

第一次調用的結果相同,但第二次調用會拋出異常。內置函數遵循一致類型規則,並且不允許不正確的參數類型。返回值也始終是一個字符串。所以我們可以說內置函數更好,但您可能想知道究竟是如何做到這一點的?讓我們考慮一下此類函數的典型用例。我們在代碼中的某個點使用它來將字符串轉換為小寫。正如 JavaScript 代碼中經常發生的那樣,我們不能 100% 確定我們的輸入是否總是字符串。沒關係,因為我們是優秀的程序員,我們假設我們的代碼沒有任何錯誤。如果我們使用不遵守這些規則的 AngularJS 函數會發生什麼?非字符串值會毫無問題地通過它。它可能會通過幾個函數,我們甚至可能會通過 XMLHttpRequest 調用發送它。現在錯誤的值在我們的服務器中,並最終進入數據庫。您可以看到我的意思,對吧?如果我們使用遵守規則的內置函數,我們會在那時立即發現該錯誤。每當您編寫函數時,請確保其返回的類型一致。下面顯示了一個不好的例子:

var text = 'Hello types';

// 错误!不要这样做!
text = 1;

同樣,與變量和參數一樣,如果我們有這樣的函數,我們就無法對它的行為做出假設。我們將需要使用 if 來檢查返回 value 的類型。我們可能會在某個時候忘記它,然後我們手中就會出現另一個錯誤。我們可以通過多種方式重寫它,以下是一種解決此問題的方法:

function sum(a, b) {
  if (typeof a === 'string') {
    a = 1;
  }

  return a + b;
}

這次我們確保所有路徑都返回一個字符串。現在更容易推斷函數的結果了。

null 和 undefined 是特殊的

到目前為止,我們實際上只討論了原始類型。當涉及到對象和數組時,您應該遵循相同的規則,但需要注意兩個特殊情況。處理引用類型時,有時需要指示沒有 value。一個很好的例子是 document.getElementById。如果找不到匹配的元素,它將返回 null。這就是為什麼我們將 null 視為與任何對像或數組共享類型的原因,但僅限於那些對像或數組。您應該避免從可能返回 Number 等原始值的函數中返回 null。 undefined 也可以被認為是引用的“無值”。出於大多數目的,它可以被視為等於 null,但由於其在其他面向對象語言中的語義,null 更為可取。

數組和 null

使用數組時,您還應該考慮空數組通常比 null 更好。儘管數組是引用類型,您可以使用 null 與它們一起使用,但通常返回空數組更有意義。讓我們來看下面的例子:

var a = [];
var b = a;

a.push('Hello');

這可能是數組最常見的用法之一。您從函數中獲取一個數組,然後對其進行迭代以執行其他操作。如果 getListOfItems 在沒有項目時返回 null,上面的代碼會發生什麼?它會拋出錯誤,因為 null 沒有長度(或任何其他屬性)。當您考慮像這樣使用數組,甚至是 list.forEach 或 list.map 時,您可以看到當沒有值時返回空數組通常是一個好主意。

類型檢查和類型轉換

讓我們更詳細地了解類型檢查和類型轉換。您應該何時進行類型檢查?您應該何時進行類型轉換?

類型轉換

類型轉換的第一個目標應該是確保您的值的類型正確。數值應該是數字而不是字符串,依此類推。第二個目標應該是您只需要轉換一次 value。進行類型轉換的最佳位置是在源處。例如,如果您從服務器獲取數據,則應該在處理接收到的數據的函數中進行任何必要的類型轉換。從 DOM 解析數據是一個非常常見的錯誤開始出現的地方。假設您有一個包含數字的文本框,並且您想讀取它。或者,它可能只是某個 HTML 元素中的屬性,它甚至不必是用戶輸入。

var text = 'Hello types';

// 错误!不要这样做!
text = 1;

由於您可以從 DOM 獲取的值通常是字符串,因此在讀取它們時進行類型轉換非常重要。在某種程度上,您可以將其視為模塊的“邊緣”。數據通過讀取它的函數進入您的 JavaScript 模塊,因此它必須將數據轉換為正確的格式。通過在模塊邊緣進行類型轉換,我們確保內部不必處理它。這在很大程度上減少了隱式類型強制轉換導致錯誤的可能性。它還允許我們編寫更少的代碼,因為我們不允許錯誤的值從邊緣進入模塊。

function sum(a, b) {
  if (typeof a === 'string') {
    a = 1;
  }

  return a + b;
}

typeof 和類型檢查

您應該只將 typeof 用於驗證,而不是根據類型分支邏輯。對此有一些例外,但這是一個很好的經驗法則。讓我們來看兩個例子:

function sum(a, b) {
  return a + b;
}

這是一個使用 typeof 進行驗證的示例。我們確保傳遞給函數的參數是正確的類型。但是,下面的示例顯示了根據類型分支邏輯的含義。

var a = [];
var b = a;

a.push('Hello');

不要這樣做。雖然有時可能需要這樣做,但這通常是設計不良的標誌。如果您發現自己經常執行這種邏輯,那麼您可能應該在代碼的早期將 value 轉換為正確的類型。如果您最終在代碼中使用了大量 typeof,這可能表示您可能需要轉換要比較的值。類型檢查通常會擴散,這通常是關於類型的設計不良的標誌。如前所述,您應該嘗試在模塊邊緣進行類型轉換,因為它允許您避免 typeof 級聯。如果您儘早進行轉換,則之後調用的任何函數都不必進行類型檢查或類型轉換。這也適用於對象:如果您發現自己使用 instanceof 進行大量檢查或檢查對像上是否存在屬性,則表示您可能應該以不同的方式構造數據。與 typeof 相同的規則也適用於 instanceof:您應該嘗試避免它,因為它可能是設計不良的標誌。但是,有一種情況是不可避免的:

var text = 'Hello types';

// 错误!不要这样做!
text = 1;

如果您的代碼需要對異常類型進行特定處理,instanceof 通常是一個不錯的選擇,因為 JavaScript catch 不允許像其他一些語言那樣按類型區分。在大多數其他情況下,您應該嘗試避免 instanceof。

結論

正如我們所發現的,JavaScript 的弱類型為我們帶來了極大的自由,但我們也必須謹慎行事。否則,我們將最終陷入一個類型混亂的局面,沒有任何意義。通過確保我們的代碼遵循一致類型規則,我們可以避免很多麻煩。當我們知道類型時,更容易推斷我們的代碼。我們不必在代碼中構建許多類型檢查來防止錯誤。如果您沒有使用強類型語言,這似乎很困難,但在您需要調試或維護代碼時,它會得到很大的回報。有關該主題的更多信息,我建議您查看 TypeScript。它是一種類似於 JavaScript 的語言,但它為該語言添加了更強的類型語義。它還有一個編譯器,當您嘗試執行一些愚蠢的操作(例如混合和匹配類型)時,它會吐出錯誤。

關於 JavaScript 中強類型語言的常見問題解答 (FAQ)

強類型語言和弱類型語言有什麼區別?

強類型語言是指變量綁定到特定數據類型的語言,任何與該類型不一致的操作都會導致錯誤。示例包括 Java 和 C 。另一方面,像 JavaScript 這樣的弱類型語言允許變量保存任何類型的數據,並且在必要時會自動進行類型轉換。如果處理不當,這種靈活性可能會導致意想不到的結果。

如何在 JavaScript 中強制執行強類型?

JavaScript 本身是一種弱類型語言,但您可以使用 TypeScript(JavaScript 的靜態類型超集)來強制執行強類型。 TypeScript 為 JavaScript 添加了靜態類型,允許在編譯時進行類型檢查。這有助於在開發過程的早期發現錯誤。 “嚴格模式”是 JavaScript 中的另一個方法,它通過為不安全的動作拋出錯誤來使語言的行為更像強類型語言。

使用強類型語言的好處是什麼?

強類型語言提供了一些好處。它們可以幫助在編譯時而不是運行時捕獲錯誤,這可以節省大量調試時間。它們還使代碼更具自文檔性,因為變量的數據類型清楚地表明了它們的使用方式。此外,它們可以使代碼更可預測且更容易推斷,因為它們可以防止意外的類型轉換。

我可以將 JavaScript 用作強類型語言嗎?

雖然 JavaScript 默認情況下不是強類型語言,但您可以使用 TypeScript 或 Flow 等工具來強制執行強類型。這些工具為 JavaScript 添加了靜態類型,允許在編譯時進行類型檢查。這有助於在開發過程的早期發現錯誤。但是,需要注意的是,這些工具不會改變 JavaScript 的底層性質;它們只是在它之上提供了一層類型安全性。

什麼是 TypeScript,它與 JavaScript 的關係如何?

TypeScript 是由 Microsoft 開發的 JavaScript 靜態類型超集。它為 JavaScript 添加了靜態類型,允許在編譯時進行類型檢查。這有助於在開發過程的早期發現錯誤。 TypeScript 代碼被轉換為 JavaScript,這意味著它可以在任何 JavaScript 運行的地方運行。它與 JavaScript 完全兼容,可以使用 JavaScript 的所有功能。

使用強類型語言的缺點是什麼?

雖然強類型語言提供了許多好處,但它們也有一些缺點。它們可能更冗長,需要更多代碼才能完成與弱類型語言相同的任務。它們還需要一個編譯步驟,這可能會減慢開發過程。此外,它們可能不太靈活,並且對於某些任務(例如處理動態數據)更難使用。

JavaScript 中的“嚴格模式”是如何工作的?

“嚴格模式”是 JavaScript 中的一項功能,它使語言的行為更像強類型語言。它會為不安全的動作拋出錯誤,例如為只讀屬性賦值或在聲明之前使用變量。這有助於在開發過程的早期發現錯誤。要啟用“嚴格模式”,只需在 JavaScript 文件或函數的頂部添加“use strict;”一行即可。

什麼是 JavaScript 中的類型強制?

類型強制是 JavaScript 中的一項功能,其中語言在必要時會自動將一種數據類型轉換為另一種數據類型。例如,如果您嘗試添加數字和字符串,JavaScript 將在執行加法之前將數字轉換為字符串。雖然這很方便,但如果處理不當,它也可能導致意想不到的結果。

如何避免 JavaScript 中的類型強制?

避免 JavaScript 中類型強制的一種方法是使用“嚴格模式”,它會為不安全的動作拋出錯誤。另一種方法是使用“===”運算符而不是“==”運算符進行比較,因為前者不執行類型強制。此外,您可以使用 TypeScript 或 Flow 等工具為 JavaScript 添加靜態類型,這有助於在編譯時捕獲與類型相關的錯誤。

強類型語言在 JavaScript 中的未來如何?

強類型語言在 JavaScript 中的使用可能會在未來增加,因為它們提供了許多好處,例如儘早捕獲錯誤並使代碼更可預測。 TypeScript 和 Flow 等工具越來越流行,並且正在開發新的工具和功能以使 JavaScript 更具類型安全性。但是,JavaScript 的靈活性和動態性將使其繼續成為許多開發人員的首選。

以上是JS中強烈打字的語言借用技術的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能