主頁 >  其他 > JavaScript型別系統缺陷與解決方案【大前端高薪訓練營】

JavaScript型別系統缺陷與解決方案【大前端高薪訓練營】

2020-11-25 00:09:28 其他

學習資料:拉勾課程《大前端高薪訓練營》
閱讀建議:文章較長,搭配文章的側邊欄目錄進行食用,體驗會更佳哦!
內容說明:本文不做知識點的搬運工,文中只記錄個人對該技術點的認識和理解,

一:編程語言的型別系統

1.強型別語言 與 弱型別語言

語言型別的強弱之分,業界并沒有權威的對比概念,所以網上有很多種不同的說法,但大部分說法的意思都在說明強型別語言有更強的型別約束,而弱型別中幾乎沒有什么約束,

以下個人學習課程之后對強型別與弱型別的理解:

  • 強型別語言:程式運行時變數型別不允許任意的隱式型別轉換型別安全),
  • 弱型別語言:程式運行時變數型別允許任意的隱式型別轉換型別不安全),

最簡單的代碼理解案例:

// 強型別語言:java、python等
100 - '50' //報語法錯誤

// 弱型別語言:javaScript
100 - '50' // 50

2.靜態型別語言 與 動態型別語言

以下個人學習課程之后對靜態型別型別與動態型別的理解:

靜態型別:程式開發時變數型別宣告后,不允許再修改編譯階段檢查型別),
動態型別:程式開發時變數型別宣告后,可以隨時發生變化運行階段檢查型別),

最簡單的代碼理解案例:

// 靜態型別語言:java
int a = 100;
a = '100';  // 報語法錯誤

// 動態型別語言:javascript
var a = 100;
a = '100';  // typeof(a) 輸出 'string'

3.主流編程語言分類

在這里插入圖片描述

二:Javascript型別系統缺陷

1.程式健壯性差

JavaScript語言本身是一種動態弱型別的解釋型語言,在具體探討它的型別缺陷之前,我們先看日常開發當中的幾個JavaScript常見型別錯誤示例:

let fn, name, age = 10, inputAge = '1';
fn()			// 運行時報錯,undefined不能當作函式物件不能呼叫
const fn1 = fn; // 潛在錯誤:fn1并不是一個方法

age = age + inputAge;// 運行不準確,但age計算不準確,同時型別轉為string也是一個潛在錯誤
<p> {name} </p> 	// 運行不準確,用戶看到undefined

從上述代碼我們可以感覺到,我們平常寫的JavaScript程式發生的很多錯誤其實都是型別錯誤,我們在找到這些錯誤并且除錯解決它花了不少時間,盡管如此,程式中依然還有很多潛在的型別錯誤沒有發現,下面思考一波發生這些錯誤的原因:

  • JavaScript是動態型別:意味著在程式開發階段,開發者開發出的源代碼沒有經過型別檢查就直接交給解釋器執行,

  • JavaScript是弱型別:意味著程式在運行階段碰到開發者造成的型別問題時,程式會自作主張的進行隱式型別轉換,無法轉換則報錯,轉換成功則回傳運算結果(有時候不是開發者所期望的運行結果,即運行不準確),

  • JavaScript既是動態型別又是弱型別,這使得JavaScript程式在運行期間很容易發生型別錯誤隱藏潛在錯誤、以及錯誤不被識別為錯誤導致程式運行不準確

2.原始解決方案

程式很容易發生型別錯誤隱藏潛在錯誤、以及錯誤不被識別為錯誤而運行不準確,一個好的開發者絕對無法認同這些事情的存在,所以我們在日常JavaScript開發中,經常會加上一些型別判斷代碼來避免錯誤的發生,如下代碼示例:

// 案例1
const obj = {};
// obj.foo();	// error
if(obj.foo){	// 防錯處理
	obj.foo();
} else {
  // xxx  
}

// 案例2
function sum (a, b) {
   return a + b
}
function sum (a, b) {	// 防錯處理
    if (!(typeOf(a)=== 'int' && typeOf(b)=== 'int')){
        throw new TypeError('arguments should be number');
    } 
   return a + b
}

在寫JavaScript時,我們會經常有意的寫這些代碼來避免或者解決型別錯誤,但是我們分析一下這樣解決型別問題的缺點:

  • 更大的開發成本:開發者除了需要撰寫代碼的核心邏輯之外,還需要花費更多的時間精力去撰寫避免型別問題的代碼,尤其在封裝給別人使用時,這個問題尤其顯著,
  • 只能解區域分問題:我們不可能在每次變數使用前都做一次型別判斷,所以這種方案只能解區域分型別錯誤,
  • 大量型別判斷代碼:這種方案需要在程式中撰寫大量型別判斷代碼來避免錯誤,這容易導致代碼量變大、核心業務代碼被隱藏、代碼不夠清晰等問題,
  • 性能問題:在運行階段需要運行這些型別判斷邏輯代碼,肯定需要消耗更多的運行時間,

上述解決方案雖然比較丑陋,但是這就是我們平常寫JavaScript代碼避免型別問題的默選方案,

先是講到JavaScript的型別系統這么多缺陷,后是講到原始解決方案還這么敷衍,有沒有突然有一種用JavaScript語言編程好差勁的感覺,難怪往前這么多人稱呼JavaScript為小丑語言,難堪大任!

JavaScript在運行期間出現的這么多型別問題,其實都是源于JavaScript本身對變數型別沒有約束,開發階段無法進行型別檢查,從而使得開發者撰寫出的JavaScript代碼容易出現編程錯誤導致的,

借鑒其它語言的做法,我們可能會想到,開發階段的型別約束會是型別判斷之外的解決JavaScript型別錯誤的另一種方案,實作上,這種思想現在有兩種主流的解決方案,即Flow 和 Typescript,它們都是通過在源代碼上加上型別宣告來實作的型別約束和型別檢查,然后通過編譯得到一份型別嚴謹的JavaScript代碼交給JavaScript解釋器執行的方式來解決的型別問題,這主要涉及到開發、檢查、編譯三個程序:

  • 開發階段:開發階段根據規則為變數加上合適的型別宣告,
  • 檢查階段:使用檢查工具根據變數的型別宣告和變數值進行匹配檢查,分為開發時檢查(代碼提示)、開發后檢查、編譯時檢查三種,
  • 編譯階段:使用編譯工具為變數移除型別宣告而后得到一份型別嚴謹的JavaScript代碼,

3.Flow解決方案

Flow是JavaScript的靜態型別檢查工具,它定義了一套型別約束與檢查規則,在檢查通過之后可以編譯出一套型別嚴謹也沒有Flow型別宣告的JavaScript代碼,解決JavaScript型別問題,下面從開發、檢查到編譯三個階段簡單說明Flow提供的解決方案是如何解決JavaScript型別問題的,具體的使用細節查閱官方檔案即可,

1):開發階段添加型別宣告

添加型別宣告涉及到三個部分,即自己代碼中的型別注解、環境下api(window / node)的型別注解以及第三方庫(引入的lib)中的型別注解,環境下api以及第三方庫的檔案中缺乏型別注解時,我們通常會通過引入型別宣告檔案的方式來解決,

下面是給自己代碼中加上型別宣告的案例:

// @flow
// test.js
function sum(m: number, n: number): number {
	return m + n
}

2):檢查階段進行型別匹配

型別檢查分為開發時檢查、開發后檢查、編譯時檢查三種,開發時檢查工具通常是IDE提供的插件,開發后以及編譯時檢查通常是使用官方提供的檢查工具,

Flow的開發時檢查工具此處不做探討,下面簡單說明一下Flow開發后檢查的作業流:

  • 安裝檢查工具flow-bin
yarn add flow-bin --dev
  • 寫入檢查配置資訊:.flowconifg
# 生成.flowconifg組態檔,在這里可以配置檢查源、檢查規則、檢查輸出位置等
yarn flow init
  • 讀取配置執行檢查
yarn flow
  • 控制臺輸出檢查結果
  • 根據檢查報告修改代碼中型別錯誤

3):編譯階段移除型別宣告

Flow源代碼中的型別注解并不符合JavaScript語法,直接丟給JavaScript解釋器執行會報錯,所以我們需要對源代碼進行編譯移除型別宣告,得到能夠被JavaScript解釋器執行的JavaScript代碼,解決JavaScript型別問題

移除JavaScript檔案中的Flow型別注解有兩種方案:

  • 使用工具庫flow-remove-types移除
# 安裝
yarn add flow-remove-types --dev
# 移除:命令引數,編譯輸入代碼的位置、編譯輸出代碼的位置
yarn flow-remove-types src -d dist
  • 使用Babel插件@babel/preset-flow移除
# 安裝
npm install --save-dev @babel/core @babel/cli @babel/preset-flow
# 配置:.babelrc檔案配置preset-flow插件
{
  "presets": ["@babel/preset-flow"]
}
# 轉換:命令引數,編譯輸入代碼的位置、編譯輸出代碼的位置
yarn babel src -d dist

三:Typescript終極解決方案

和Flow一樣,TypeScript也是JavaScript的型別檢查器,不同的是,Typescript功能上更強大更完善,生態上也更加健全,在語法上,Typescript是Javascript的超集,它與JavaScript的關系如下圖:
在這里插入圖片描述

以下是除官話外,個人對Typescript的認識:

Typescript這門語言其實并不能和C、C++、Java、JavaScript這些語言相談并論,它只能算是JavaScript的切面語言,因為它的變數型別和語法規則只涉及到開發和編譯階段,在編譯之后轉換為JavaScript交給JavaScript解釋器執行,這也意味著,我們在學習typescript這門語言的型別和語法時,完全不必要關注它的運行機制與存盤規則,而是只需要理解它與JavaScript型別和語法的映射關系即可,

下面我們從開發編譯兩個階段簡單說明Typescript提供的解決方案是如何解決JavaScript型別問題的,具體的使用細節查閱官方檔案即可,

1.開發階段使用Typescript語法

從上圖我們也可以看到,Typescript除了支持靜態型別之外,還支持ES6語法,接下來我們主要關注它是怎么解決JavaScript的型別問題的,
與Flow一樣,Typescript的型別宣告也涉及到到三個部分,即自己代碼中的型別注解、環境下api(window / node)的型別注解以及第三方庫(引入的lib)中的型別注解,環境下api以及第三方庫的檔案中缺乏型別注解時,我們通常會通過引入型別宣告檔案的方式來解決,

下面是給自己代碼中加上型別宣告的案例:

// test.ts
function sum(m: number, n: number): number {
	return m + n
}
開發時檢查

typescript可以歸屬于靜態語言,IDE對其代碼具備很強的感知能力,所以IDE可以為開發者提供很強大的開發時檢查、代碼提示、錯誤提示等功能,

2.編譯階段轉換Typescript語法

與Flow一樣,Typescript源代碼也不能直接交給JavaScript解釋器執行,我們需要使用官方提供的tsc工具將typescript代碼編譯為JavaScript代碼,解決Javascript的型別問題

以下簡要說明Typescript的編譯作業流:

  • 安裝typescript
yarn add typescript --dev
  • 寫入編譯配置:tsconfig.json
# 1.生成.flowconifg組態檔,在這里可以配置檢查源、檢查規則、檢查輸出位置等
yarn tsc --init

# 2.修改tyscript組態檔,主要涉及到編譯輸入檔案位置、輸出檔案位置、編譯規則等
# xxx
  • 讀取編譯配置執行編譯
yarn tsc
  • 編譯結束,成功得到JavaScript代碼,失敗則根據編譯報錯資訊修改代碼,

3.Typescript型別系統

這里簡單提一提Typescript的型別系統,Typescript官網檔案對它的型別劃分為以下幾類:

型別含義示例
basic Types基本型別number、Tuple、Void…
Interfaces介面型別{ x : ‘xx’ } / interface xxx { x ‘xx’}
Unions and Intersection Types并集、交集型別object | null
Literal Types字面量型別1 | 2 | 3
Enums列舉型別Enum x { x ‘1’ }
Functions函式型別function (m: number): Void { // xxx,no return }
Classes型別別完整的java類,訪問控制,單繼承多實作
Generics泛型值泛型:Array<number>,函式泛型、類泛型

Typescript作為新出現的靜態語言,它的型別系統吸收了很多其它語言中優秀的型別,尤其是Java,其實對于這些各種型別約束,我們也可以等同的使用原始解決方案為代碼加上型別判斷來解決型別問題,使用typescript雖然會造成初期開發增加,但是它可以讓我們不用大量的型別判斷就可以寫的一手型別嚴謹、性能更好、維護性更好的JavaScript代碼,如果想做一位JavaScript的優秀coder,不用我說也會擁抱Typescript吧!

對于typescript的學習成本,其實它的學習成本很低,特別是對于有靜態語言使用經驗的開發者來說,因為它只涉及到開發和編譯階段,我們只需要理解它的各種型別含義并熟悉運用就可以寫的一手好Typescript代碼,

本文結束,謝謝觀看,
如若認可,一鍵三連,每周一篇,后續更多精彩,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/227185.html

標籤:其他

上一篇:假設Tom和Jerry利用Java UDP進行聊天

下一篇:C語言宏定義使用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more