[TOC]
## 數據類型分類
> JS中的數據類型
> - 基本數據類型(值類型)
> + number(NaN)
> + string
> + boolean
> + null
> + undefined
其中,null、undefined也可被分為特殊數據類型
> - 引用數據類型
> + 對象
> + {} 普通對象
> + [] 數組
> + /^$/ 正則
> + Math等系統對象
> + ...
> + 函數
> + function 普通函數
> + 類->class
> + ...
## 數據類型操作原理
JS代碼運行在瀏覽器中,是因為瀏覽器給我們提供了一個供js代碼執行的環境,我們把這個環境稱之為**全局作用域**(window/global)

### 值類型是按照值來操作
```
//會把12這個原值直接賦給變量a(a變量直接和12這個值建立了鏈接)
var a = 12;
var b = a; //->b=12
b=13;
console.log(a);
```
```
<<<
12
```
### 引用數據類型是按照地址來操作
因為對象類型不再是一個簡單的值,而會是很多值的集合,so需要開辟一個空間(相當于一個箱子)用來存放它。
操作步驟:
1. 遇到對象類型的數據,會先開辟一個新的內存空間,瀏覽器會分配給它一個16進制的地址(方便別人找到它)。
2. 按照一定的順序,分別的把對象鍵值對存儲到新開辟的內存空間當中。
3. 把開辟內存的地址賦值給變量(或則其它的東西,比如說當前元素的某個事件),以后變量就可以通過地址找到內存空間,然后進行一些操作。
>**注意:** 相關的,`const`常量之所以無法改變,就是因為定死了地址(地址對應的空間內的內容不是定死的),故它叫“常”而不叫“變”,這個“量”你可以認為它就是地址,不變的地址,可變的地址。
```javascript
var o = {name='ahhh'}; //o = aaafff111
var p = o; //p = aaafff111
p.name = 'ahhh2'; //p通過地址找到對應的內存空間,再把里面的name改成ahhh2
console.log(o.name);
```
```
<<<
ahh2
```
```javascript
var m = {name:'ahhh'}; //m = aaafff111
var n = m;
n = {name:'ahhh2'}; //n = aaafff222 ,這里開辟了另外一個新的空間,并且把這個新空間的地址給了n
console.log(m.name);
```
```
<<<
ahhh
```
### 函數的操作原理
> 創建函數
> 1、 先開一個新的內存空間(瀏覽器為其分配一個十六進制的地址)(和給普通對象開辟的空間一樣)
> 2、把函數體中編寫的js代碼當做`字符串`存儲到空間中
> (函數只創建不執行沒有意義)(和普通對象相比,普通對象存儲的是有意義的鍵值對(能通過.x找到對應的鍵值),函數存儲的是無意義的字符串)
> 3、 把分配的地址賦值給聲明的函數名
>[warning]**注意:** function fn 和 var fn 操作原理其實相同,都是在當前作用域中聲明了一個名字,此處兩個名字是重復的,不會報錯,后者會覆蓋前者
> 執行函數
> 目的:執行函數體中的代碼
> 1、 函數執行的時候(**每一次執行**),瀏覽器會形成一個新的私有作用域(只能執行函數體中的代碼),供函數體中的代碼執行。
> 2、執行代碼之前,先把創建函數存儲的那些字符串變為真正的js表達式,按照從上到下順序在私有作用域中執行
>[danger] **注意:** 函數每次執行都會形成一個**新的**私有作用域,每次都是把存在內存中的函數體字符串copy一部分出來執行。兩次之間沒有直接關系但可能存在間接關系(比如說在全局下有個變量,你在函數內用到了)。
>[danger] **注意:** 形成的私有作用域會把函數體中的私有變量都包裹起來(保護起來),在私有作用域中操作私有變量和外界沒關系,外界也無法直接的操作私有變量,我們把函數自執行形成的這種保護機制叫做**閉包**。
```
function fn(){
var ary = Array.prototype.slice.call(arguments)
return eval(ary.join('+'));
}
fn(12,23,34,45,56);
```
## 棧內存與堆內存
### 棧內存
也叫作用域(全局作用域、私有作用域),它有兩個作用:
- 為JS代碼提供執行的環境(執行js代碼的地方)
- 基本數據的值是直接存放在棧內存中的
### 堆內存
存儲引用數據類型值的(相當于一個存儲的倉庫)
- 對象存儲的是鍵值對
- 函數存儲的是代碼字符串
### 回收
在項目中,我們的內存越少性能越好,我們需要把一些沒用的內存處理掉
#### 堆內存的釋放
```javascript
//當前對象對應的堆內存被變量o占用著,此時堆內存是無法銷毀的
var o = {};
//--- --- ---
o = null; //null叫空對象指針,不指向任何的堆內存,此時上一次的堆內存就沒有被占用了,可以釋放了,
```
谷歌瀏覽器會在空閑時間把沒有被占用的堆內存自動釋放(銷毀/回收)。
IE瀏覽器有計數器,沒有被占用時,計數器就會置為0,就會觸發回收。
#### 棧內存的釋放
一般情況,函數執行形成棧內存,函數執行完,瀏覽器會把形成的棧內存自動釋放。
但有時候執行完成,棧內存不能被釋放
### 全局作用域的執行以及釋放
全局作用域在加載頁面時執行
在關掉頁面時銷毀

## FAQ

- 空白目錄
- window
- location
- history
- DOM
- 什么是DOM
- JS盒子模型
- 13個核心屬性
- DOM優化
- 回流與重繪
- 未整理
- 文檔碎片
- DOM映射機制
- DOM庫封裝
- 事件
- 功能組件
- table
- 圖片延遲加載
- 跑馬燈
- 回到頂部
- 選項卡
- 鼠標跟隨
- 放大鏡
- 搜索
- 多級菜單
- 拖拽
- 瀑布流
- 數據類型的核心操作原理
- 變量提升
- 閉包(scope)
- this
- 練習題
- 各種數據類型下的常用方法
- JSON
- 數組
- object
- oop
- 單例模式
- 高級單例模式
- JS中常用的內置類
- 基于面向對象創建數據值
- 原型和原型鏈
- 可枚舉和不可枚舉
- Object.create
- 繼承的六種方式
- ES6下一代js標準
- babel
- 箭頭函數
- 對象
- es6勉強筆記
- 流程控制
- switch
- Ajax
- eval和()括號表達式
- 異常信息捕獲
- 邏輯與和或以及前后自增
- JS中的異步編程思想
- 上云
- 優化技巧
- 跨域與JSONP
- 其它跨域相關問題
- console
- HTML、XHTML、XML
- jQuery
- zepto
- 方法重寫和方法重載
- 移動端
- 響應式布局開發基礎
- 項目一:創意簡歷