JavaScript基本類型數據都是直接按值存儲在棧中的(Undefined、Null、不是new出來的布爾、數字和字符串),每種類型的數據佔用的內存空間的大小是肯定的,並由系統自動分配和自動釋放。這樣帶來的好處就是,內存能夠及時獲得回收,相對於堆來講 ,更加容易管理內存空間。javascript
JavaScript引用類型數據被存儲於堆中 (如對象、數組、函數等,它們是經過拷貝和new出來的)。其實,說存儲於堆中,也不太準確,由於,引用類型的數據的地址指針是存儲於棧中的,當咱們想要訪問引用類型的值的時候,須要先從棧中得到對象的地址指針,而後,在經過地址指針找到堆中的所須要的數據。java
Symbol表示獨一無二的值(須要注意的是經過 Symbol()方法建立值的時候不能使用 new 操做符,緣由是經過 new 實例化的結果是一個 object 對象,而不是原始類型的 symbol)
數組
const opt1 = Symbol('key');
const opt2 = Symbol('key');
const obj = {
[opt1]: 'value',
[opt2]: 'value',
}
// obj:{Symbol(key): "value", Symbol(key): "value"}
複製代碼
// a.js
const privateKey = Symbol('key')
class myClass{
constructor(){
this.name = 'test'
// 由於Symbol獨一無二的特性,此處的屬性只能在a.js中被訪問,
// 新建出來的實例也沒法訪問該屬性,本質上是沒法訪問privateKey。
this[privateKey] = 'strange'
}
}
複製代碼
如 String、Number、Boolean、Object、Function、Array、Date、RegExp、Error。實際上這些是一些內置函數,這些內置函數能夠當作構造函數來使用,從而建立一個對應子類型的新對象。安全
具體不展開,詳見 juejin.cn/post/684490…markdown
undefined的字面意思是:未定義的值。在試圖讀取未定義或者定義了未賦值的變量時會返回。數據結構
null的字面意思是:空值。在內存中能夠表示爲棧中的指針地址沒有指向堆中的內存對象。(在JS最初的實現中,中的值是由一個表示類型的標籤和實際數據值表示的,對象的類型標籤是0。因爲null表明的是空指針0x00,所以,null的類型標籤也成爲了 0,typeof null就錯誤的返回了"object")函數
判斷數組:Object.prototype.toString.call(new Array()) === '[object Array]'post
緣由:JS 遵循 IEEE 754 規範,採用雙精度存儲(double precision),佔用 64 bit。1位用來表示符號位,11位用來表示指數,52位表示尾數。ui
由於在計算機最底層,數值的運算和操做都是採用二進制實現的,因此計算機沒有辦法精確表示浮點數,而只能用二進制近似相等的去表示浮點數的小數部分。this
0.1 >> 0.0001 1001 1001 1001…(1001無限循環)
0.2 >> 0.0011 0011 0011 0011…(0011無限循環)
0.1+0.2 = 0.01001100110011001100110011001100110011001100110011001110
轉十進制0.30000000000000004
複製代碼
當進行計算或其餘操做時時,四捨五入(逢1進,逢0舍)將會致使最終的運算結果存在誤差。
而大整數也存在一樣的問題,由於表示尾數的尾數只有52位,所以 JS 中能精準表示的最大整數是 Math.pow(2, 53),即十進制9007199254740992。(ES2015的BigInt就是用來解決大數問題)
能夠引入Math.js等一些專門處理此問題的三方庫來解決精度丟失。