原始值是不能夠修改的,非原始值是能夠修改的。javascript
計算機程序的運行須要對值進行操做,可以表示並操做的值的類型稱作數據類型(type)。程序須要將值保存起來以備未來使用時,便將其賦值給一個變量,變量是一個值的符號名稱,能夠經過名稱來得到對值的引用。java
對象是屬性的集合,每一個屬性都由名/值對構成。web
IEEE754標準中規定:對於 float 單精度浮點數在機器中,用 1 位表示數字的符號,用 8 位來表示指數,用23 位來表示尾數,即小數部分;對於 double 雙精度浮點數在機器中表示用 1 位表示符號,用 11 位表示指數,52 位表示尾數,即小數部分。數組
其中指數域稱爲階碼,對階碼 E 的計算採用源碼的計算方式,32位浮點數的 8bits 的階碼E的取值範圍是 0 到 255;64位的浮點數的 11bits 的階碼E的取值範圍是 0 到 1023;其中當E爲全0或者全1時。瀏覽器
階碼的二進制位數決定浮點數的表示範圍,尾數的二進制位數表示浮點數的精度。以32位浮點數爲例,尾數域有23位。那麼浮點數以二進制表示的話精度是23位,23位所能表示的最大數是,因此十進制的尾數部分最大數值是8388607函數
JavaScript 中的數字格式,可以表示的整數範圍是從 -2 ~ 2,包含邊界值。然而須要注意的是 JavaScript 中實際的操做是基於32位整數。
ui
當數字運算結果超過 JavaScript 所能表示的數字上限,結果爲一個特殊的無窮大(Infinity)值。一樣地,當負值超過了 JavaScript 所能表示的數字下限,結果爲一個特殊的負無窮大(-Infinity)值spa
當運算結果無限接近於零並比 JavaScript 能表示的最小值還小的時候發生的一種情形。這種狀況下,JavaScript 將會返回 0。code
零除以零是沒有意義的,這種整除運算結果也是一個非數字(not-a-number)值,用 NaN 表示。cdn
0 / 1 //0
0 / -1 // -0
0 === -0 // true
1 / 0 // Infinity
-1 / 0 // -Infinity
Infinity === -Infinity // false
Infinity + Infinity // Infinity
-Infinity - Infinity // -Infinity
0 / 0 // NaN
Math.sqrt(-1) // NaN
-Infinity + Infinity // NaN
NaN === NaN // false
isFinite(NaN) // false
null + null // 0
undefined + undefined // NaN
複製代碼
JavaScript 採用了 IEEE754 浮點數表示法,這是一種二進制表示法,能夠精確地表示分數,好比 1/二、1/8 和 1/1024。遺憾的是,咱們經常使用的分數都是十進制 1/10,1/100等,二進制浮點數表示法並不能準確表示相似 0.1 這樣簡單的數字。
0.1 + 0.2 !== 0.3
0.3 - 0.2 !== 0.2 - 0.1
複製代碼
字符串是一組由16位值組成的不可變的有序序列,每一個字符一般來自 Unicode 字符集。JavaScript 經過字符串類型來表示文本,字符串的長度是其所含 16 位值的個數。
在 JavaScript 中字符串是固定不變的,相似 replace()
和 toUpperCase()
的方法都返回新字符串,原字符串自己並無發生變化。
只有兩個值,保留字 true 和 false。JavaScript 程序中的比較語句的結果一般都是布爾值。
undefined、null、0、-0、NaN、'' 在 JavaScript 中會被轉換成 false。
null 表示一個特殊值,經常使用來描述 "空值",對 null 執行 typeof 其結果返回字符串 "object",也就是說,能夠將 null 認爲是一個特殊的對象值,含義是 "非對象"。
undefined 是預約義的全局變量,他的值是 "未定義",若是函數沒有返回任何值,則返回 undefined;引用沒有提供實參的函數形參的值也是 undefined。使用 typeof 運算符獲得的值是 "undefined"。
數字、布爾值、字符串能夠經過 Number()、Boolean()、String() 構造函數建立一個臨時對象,方法的調用均是來自這個臨時對象,若是試圖給其屬性賦值,會忽略其操做,修改操做只是發生在臨時對象身上,而這個臨時對象並未繼續保留下來。
存取字符串、數組或布爾值的屬性時建立的臨時對象稱作包裝對象。還能夠經過 Number()、Boolean()、String() 構造函數來顯示建立包裝對象。
null 和 undefined 沒有包裝對象。
s1 = new String('hello')
s1.len = 4
t1 = s1.len // 4
s1 = 'hello'
s1.len = 4
t1 = s1.len // undefined
n1 = 1;
n2 = new Number(n1)
n1 == n2 // true
n1 === n2 // false
typeof n1 // "number"
typeof n2 // "object"
複製代碼
JavaScript 中的原始值(undefined、null、布爾值、數組和字符串)是不可更改的,任何方法都沒法更改一個原始值;原始值的比較是值的比較,只有在它們的值相等時,它們才相等。
對象是可變的,它們的值是可修改的;對象的比較均是引用的比較,當且僅當它們引用同一個基本對象時,它們才相等。
因爲 JavaScript 能夠作靈活的類型轉換,所以其 ""
相等運算符也隨相等的含義靈活多變。在進行 ""
等於運算符判斷兩個值是否相等時,會作類型轉換。
最簡式的方法是使用 Boolean(),Number(),String() 或 Object() 函數,不經過 new 運算符調用這些函數時,會做爲類型轉換函數進行類型轉換。
Number 類的 toString() 方法能夠接收並注入和基數的可選參數。若是不知道此參數,轉換規則是基於十進制。
Number 類的 toFixed() 根據小數點後的指定位將數字轉換爲字符串。
對象轉字符串和數字的規則只使用本地對象(native object),不適用宿主對象(eg: web 瀏覽器定義的對象)
做用是返回一個反映這個對象的字符串
({a: 1}).toString() // "[object Object]"
數組類的 toString() 方法將每一個數組元素轉爲字符串,並在元素直接添加逗號後返回字符串
[].toString() // ""
[1, 2].toString() // "1,2"
函數類的 toString() 方法返回這個函數的實現定義的表示方式
(function f() {fn(1)}).toString() // "function f() {fn(1)}"
RegExp類的 toString()方法將 RegExp 對象轉換爲正則表達直接量的字符串
/\d+/.toString() // "/\d+/"
日期類的 toString() 方法返回一個可讀的日期和時間字符串
(new Date()).toString() // "Sat Feb 01 2020 21:46:17 GMT+0800 (中國標準時間)"
複製代碼
若是存在任意原始值,它就默認將對象轉換爲表示它的原始值。對於對象來講,沒法真正表示一個原始值,默認返回對象自己。
數組、函數、正則的 valueOf() 默認返回對象自己
({a: 1}).valueOf() // {a: 1}
[1, 2].valueOf() // [1, 2]
[].valueOf() // []
/\d+/.valueOf() // /\d+/
(function f() {fn(1)}).valueOf() // f() {fn(1)}
日期類的 valueOf() 返回時間戳
(new Date()).valueOf() // 1580565225890
複製代碼
"+" 和 "==" 應用的對象(非日期類)到原始值的轉換基本上都是對象到數字的轉換(首先調用 valueOf());日期對象則使用對象到字符串的轉換模式(首先調用 toString())。經過 valueOf 或 toString 返回的原始值被直接使用,而不會被強制轉換爲數字或字符串。
變量的做用域(scope) 是程序源代碼中定義這個變量的區域,在函數內聲明的變量和函數參數定義的變量都是局部變量,做用域在函數體內有效。
函數做用域(function scope):變量在聲明它們的函數體以及這個函數體嵌套的任意函數體內都是有定義的。
聲明提早(hoisting): 函數內聲明的全部變量在函數體內始終是可見的,即函數裏聲明的變量會被提早至函數體的頂部。
當聲明一個 JavaScript 全局變量時,其實是定義全局對象的一個屬性。
每一段 JavaScript 代碼都有一個與之關聯的做用域鏈(scope chain),這個做用域鏈是一個對象列表或鏈表,這組對象定義了這段代碼做用域中的變量。
做用域鏈由一個全局對象組成,在不包含嵌套的函數體內,做用域鏈上有兩個對象,第一個是定義函數參數和局部變量的對象,第二個是全局對象。在一個嵌套的函數體內,做用域鏈上至少有三個對象。
當建立一個函數時,它實際上保存了一個做用域鏈;當調用這個函數時,它建立了一個新的對象來存儲它的局部變量,並將這個對象添加至保存的那個做用域鏈上,同時建立一個新的更長的表示函數調用做用域的鏈。