在剛開始接觸JavaScript時,常常會聽到有人說JavaScript是個 弱型別 的程式語言,那時候對於這句話的解讀是:因為JavaScript 的不嚴謹以及他的型別會自動轉換,所以才說它是弱型別 的程式語言。
直到2023的今天我才知道這樣的說法『不完全正確』,應該是要說:
JavaScript 是”動態型別”加”弱型別” 的程式語言
那什麼是動態型別?既然有動態型別是不是也有靜態型別,下面我們就來看一下兩者的不同之處:
in Java(static typing):
bool isNew = 'hello'; // an error
// 設定這個變數是bool,所以當我放入true/false以外的字都會出現錯誤
編譯式語言多半是靜態語言,Java 和 C# 是其中的代表。
這類語言在型別的管理上十分嚴謹,在語法撰寫時就會要求對變數型別有明確定義,有時讓人覺得囉嗦;但相對的,一旦有變數誤用或資料型態上的 Bug,在編譯時期就能發現,降低執行時期的風險。
in JavaScript (dynamic typing):
var isNew = true; // no errors
isNew = 'yup!'
isNew = 1
在程式執行過程才會進行資料型態的檢查或確認,因此直譯式語言都是動態語言。如 Python、PHP、Ruby,還有 JavaScript,都屬於此類語言。
這類語言在程式編寫時,不用花太多心思在宣告型別的語法上,簡潔而靈活,可以在過程依需求任意改變型別,做到十分靈活的變數處理;但相對缺乏對當前變數的型別限制,當執行到某一行程式時,無法絕對肯定變數現在放了什麼類型的值時,容易造成非預期的執行可能性,導致非預期的執行結果。
了解了動態型別跟靜態型別後,接下來我們來看一下強型別跟弱型別:
所謂的隱性型別轉換如下:
const a = 1;
const b = '2'
console.log(a + b)
在可以隱性型別轉換的程式語言(如JavaScript)會因為變數是number + string,兩個型別不同而自動把第一個參數轉換成string,因此輸出結果就會是:12(這是字串)
但如果是在不可以隱性型別轉換的程式語言(如Java),就會直接噴錯
因此動態型別加上過於寬鬆的弱型別,就有人認為是 JavaScript 最叫人頭痛的萬惡根源。
答案是2個:Primitive type 跟 object。分法很簡單只要不是Primitive type就是屬於 object,XD。
說正經的,Primitive type總共有7種,只要不屬於這7種的就是object。
這邊要特別注意一點,變數本身是沒有型別的,是變數的值才有型別之分。
另外在JavaScript中,Primitive type 是不可變(immutable)的,而Objects 是可變(mutable)的。
這是因為Primitive type在賦值或操作時,是直接複製其值到新的變數,而不會影響原始值本身。而Objects 則是引用類型,賦值或操作時是傳遞的是物件的引用(記憶體地址),因此改變新變數的值會影響原始物件,關於這段會在傳值還是傳址的篇章在做說明。
簡單介紹了一下強弱型別以及動態型別、靜態型別,接下來就是要來介紹Primitive type 跟 objects了