Javascript
, data type
, string
原始資料型別都有「原始值 (primitive value)」,且原始值是不可被更改的。
Javascript 的七種原始資料型別:
true
/ false
NaN
- Not a Number除此之外,還有第八種:
Ref: https://developer.mozilla.org/en-US/docs/Glossary/Object
The
typeof
operator returns a string indicating the type of the operand's value.
只有 typeof
null
會返回 "object"
。要確認一個值是否為 null
時,可使用 === null
來檢驗該值是否為 null
。
JavaScript is a dynamic language with dynamic types.
JavaScript is also a weakly typed language
上述例子中, 數字變數 age
與字串變數 myName
相加, age
的值 18
被自動轉型成字串 "18"
,因此相加結果 total
為 Tom18
+
:當數字與字串相加,數字被轉型成字串-
:當數字與字串相減,字串被轉型成數字parseInt(string)
、parseFloat(string)
Number()
+
、−
) Unary Operator除了上述的方法外,還可以運用 Javascript 的一元正號運算子(Unary Plus)、一元負號運算子(Unary Negation),將其轉換成數字。
在字串前方加上 +
或 -
來將字串轉型為數字並取其數值:
.toString()
The
toString()
method of Number values returns a string representing this number value.
undefined
是型別 Undefined 的值,且 Undefined 這個型別就只有 undefined
這個值。
當一個變數沒有被賦予任何值的時候,Javascript 會給予它一個預設值 undefined
:
使用 typeof undefined
也會得到 undefined
:
注意: typeof
回傳的值是字串,所以 'undefined'
需以字串表示
null
是型別 Null 的值,且 Null 這個型別也就只有 null
這個值。它的意思是「存在但沒有值」。null
是刻意讓開發人員用來宣告「空值」用的,Javascript 並不會將值設定為 null
。
使用 typeof Null
會得到 object
:
這是 Javascript 最著名的 bug 之一,詳細情形可以看這篇:The history of “typeof null”
關於 Null / Undefined / Not defined 的詳細說明與比較,有另外整理了一篇:Javascript - Null, undefined, not defined 差異
Javascript 的 Boolean 用來表示真或假,只會有兩種值:
true
- 表示真false
- 表示假在 JavaScript 中,只有這些值會被當作是 false
:
undefined
null
false
值0
、-0
(數值)NaN
''
、""
空字串除了這些值以外的值都會是 true
!
使用 Boolean()
可以用來將其他的資料型態轉型 (type conversion) 成布林值型態:
轉換後會得到 false
的,就稱作 「falsy」值;會變成 true
的則稱作 「truthy」值。
全域的 Boolean 物件自身沒有任何方法,它只有從原型鏈繼承而來的方法。
所有 Boolean 實體(Instance) 會繼承 Boolean.prototype 。和所有建構式一樣,原型物件會指派給實體那些繼承的屬性和方法。
Boolean.prototype.toString()
轉換將布林值轉換成字串('true'
, 'false'
)
Boolean.prototype.valueOf()
取得布林物件的原始值 (true
, false
)
在判斷式中,任何物件只要不是 undefined
或 null
,儘管是值為false
的 Boolean 物件,都會被轉換成 true
。
Do not use the
Boolean()
constructor withnew
to convert a non-boolean value to a boolean value — useBoolean
as a function or a double NOT instead
注意,不要用 Boolean 物件(new Boolean()
)將非布林值轉換成布林值,應將 Boolean 視為函式(Boolean()
)去轉換非布林值:
舉例來說,下列的 if 判斷式中的布林值即為 true
:
以上的例子是建立了一個新的 Boolean 物件,和 Boolean 原始型別沒有關連,因此 x 為 truthy。
下列的 if 判斷式才會正確地將其視為 false
:
The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values (“elements”) up to a maximum length of 2^53 - 1 elements.
The String type is generally used to represent textual data in a running ECMAScript program, in which case each element in the String is treated as a UTF-16 code unit value (p.72)
來自「來數數 JavaScript 的所有資料型別」的翻譯蒟蒻:
字串就是一連串的 16-bit 的數字,而這些數字就是 UTF-16 的 code unit,字串的長度最多則是 2^53 - 1。
.length
屬性,獲取字元串長度This property returns the number of code units in the string
String 的 length
屬性(property)包含著該字元串的長度(包含空白與標點符號)。
空字串的 length
為 0
:
靜態屬性 String.length
與字串長度無關,它是 String 函數的參數數量,也就是 1
為字串的 length
屬性重新賦值不會有任何作用(在 strict mode 下會報錯):
Javascript 是使用 UTF-16 編碼,每個 Unicode 字符可以編碼成一到兩個碼元(code unit)。也就是說,對於 Javascript 來說所有的字串都是一系列的 UTF-16 碼元。
length
指的是碼元的個數(code units)而不是字元數(characters),因此 length
返回的值可能與字串中 Unicode 實際的字符數量不一致。
如果想要取得正確的字元數,可以使用迭代器(iterator),將字串分隔成字元。或使用 Array.from(str).length
。
.trim()
方法,去掉字串頭尾空白trim()
:去掉前後空白trimStart()
:去掉起始空白trimEnd()
:去掉結尾空白使用 .concat()
方法,
使用相加運算子 (+
)
.charAt(index)
方法:
introduced in ECMAScript 6 (2015)
``
${value}
for variablesNumber values represent floating-point numbers like
37
or-9.25
.
可以使用 Number(value)
將參數轉換成數字,如果參數無法被轉換成數字則返回值為 NaN
:
使用 Number()
返回的值:
undefined
turns into NaN
.null
turns into 0
.true
turns into 1
; false
turns into 0
.NaN
.BigInts
throw a TypeError
to prevent unintended implicit coercion causing loss of precision.Symbols
throw a TypeError
.[@@toPrimitive]()
(with "number" as hint), valueOf()
, and toString()
methods, in that order. The resulting primitive is then converted to a number.The Number type has exactly 18,437,736,874,454,810,627 (that is, 2^64 - 2^53 + 3) values, representing the double-precision 64-bit format IEEE 754-2019 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9,007,199,254,740,990 (that is, 2^53 - 2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (p.76)
Javascript 的 Number 是用 64 bit 來存,遵循的規格是 IEEE 754-2019。64 bit 是個有限的空間,但數字卻是無限的。這代表 Number 是一個有限範圍的數字(有儲存上限)。
我們可以使用 Number.MAX_SAFE_INTEGAR
來拿到正整數的安全範圍,即:2^53 - 1
,也就是 9007199254740991
。
安全範圍內的數字可以被明確地表示&比較,一但超出這個範圍就有可能會有誤差。
Infinity
或 -Infinity
是 JavaScript 的一個 global 屬性,用來表示無限大或無限小。
NaN(Not a Number) 顧名思義就是非數字。
typeof NaN // Number
NaN
不等於任何值,也不等於自己NaN === NaN // false
關於 NaN 的詳細說明:Javascript - NaN (Not a Number)
BigInt 是 ES2020 新增的型別:
BigInt values represent numeric values which are too large to be represented by the number primitive.
這邊的 "too large" 指的是超越了上述 Number 所說的安全範圍 MAX_SAFE_INTEGER
,也就是大於 2^53
的整數。
透過在數值尾端加上一個 n
或呼叫 BigInt(value)
來生成一個 BigInt
:
上面當 Number 超越安全範圍時導致運算有誤差的例子,只要改為使用 BigInt
就不會有問題:
使用 typeof
檢查型別時,一個BigInt
會回傳 "bigint"
:
Number
和 BigInt
不能混合計算,如果要運算,必須先被轉換成同樣的型別。然而, BigInt
在被轉換成 Number
時可能會遺失部分精度的資訊。因此,建議當數值會超過 2^53
時只使用 BigInt
,而不要在兩者之間進行轉換。
Symbol 是 ES6 新增的型別。
The Symbol type is the set of all non-String values that may be used as the key of an Object property.
Each possible Symbol value is unique and immutable.
Each Symbol value immutably holds an associated value called [[Description]] that is either undefined or a String value. (p.73)
由此我們可以知道:
Every
Symbol()
call is guaranteed to return a unique Symbol.
使用 Symbol()
建立一個獨一無二的 Symbol:
Symbol 獨一無二的特性讓它在被當成物件的 key 使用時,不需要擔心會與其他的 key 衝突。
Every
Symbol.for("key")
call will always return the same Symbol for a given value of "key"
使用 Symbol.for("key")
來獲取相同的或創建一個新的 Symbol:
When Symbol.for("key") is called, if a Symbol with the given key can be found in the global Symbol registry, that Symbol is returned. Otherwise, a new Symbol is created, added to the global Symbol registry under the given key, and returned.
這時候 sym1 === sym2
為什麼又是 true
了呢?
實際上,當你呼叫 Symbol.for("key")
函式時,Javascript 會先在全域的 Symbol registry 裡找該 key 的 Symbol。
如果有找到,則會回傳該 Symbol;如果沒有找到,就會建立一個新的 Symbol ,並且寫入 Symbol registry 中,然後回傳該 Symbol。
Symbol 的另一個特性是隱藏資訊,當你在用 for...in
loop 的時候,如果 key 是 Symbol 型別,並不會被列出來:
要建立全域(甚至跨文件、跨域)的 Symbol ,可以透過使用 Symbol.for()
和 Symbol.keyFor()
來註冊和取得 global registry 裡的 Symbol。
需注意,這裡說的 global symbol registry 只是一個抽象的概念,並真的存在於 Javascript 的資料結構中。
Symbol.for(tokenString)
takes a string key and returns a symbol value from the registry.
Symbol.keyFor(symbolValue)
takes a symbol value and returns the string key corresponding to it.Each is the other's inverse
使用 Symbol.for(tokenString)
:
使用 Symbol.keyFor(symbolValue)
:
An Object is logically a collection of properties.
Properties are identified using key values. A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty String, are valid as property keys. A property name is a property key that is a String value.
Property keys are used to access properties and their values(p.89)
key
,使用 key
來取得物件的屬性和對應的值key
一定要是 string
或 symbol
;即使是空字串也可以拿來當作 key使用 obj.key
或 obj['key']
來獲取物件的屬性與值
使用 delete
運算子移除物件的屬性:delete obj.key
,其返回值在大多數情況下皆為 true
。