文 / 景朝霞
來源公號 / 朝霞的光影筆記
ID / zhaoxiajingjing
圖 / 本身畫
❥❥❥❥點個贊,讓我知道你來過~❥❥❥❥
【前情提要】javascript
【iview】java
var a = 10; var obj = { id:'zhaoxiajingjing', name:'公號:朝霞的光影筆記' }; function func(a) { console.log(a); } func(1);
△圖13.1:代碼的圖解web
內存分爲:棧內存(stack),堆內存(heap);以谷歌的webkit爲例,要清楚咱們本身在打開瀏覽器時產生的堆棧內存:編程
(1)在瀏覽器中打開頁面,瀏覽器引擎會渲染相關的代碼(包括JS代碼),把代碼自上而下執行數組
(2)瀏覽器想要執行代碼,會提供一個供代碼執行的環境:Execution Context Stack(執行環境棧ECStack)棧內存瀏覽器
(3)最開始執行的是全局代碼,因此會造成一個Execution Context(Global)全局執行上下文(EC(G)),在棧內存中執行全局代碼閉包
(4)在全局的執行上下文中有一個Variable Object (Global) 全局變量對象(VO(G)是有瀏覽器底層語言寫的),能夠把須要定義的變量和對應的值存儲在這裏iview
(5)var a =10;
函數
① 建立一個值10(基本數據類型直接存儲在棧內存中)oop
② 建立一個變量a(把其直接存儲在VO(G)中)
③ 讓建立的變量a和值10關聯在一塊兒(賦值操做)
(6)let obj = {id:'zhaoxiajingjing', name:'公號:朝霞的光影筆記'};
① 建立值:
1)開闢一個 堆內存(heap),每個堆內存都有一個16進制的地址2)把對象中的鍵值對分別存儲在堆內存中
3)把堆內存的地址存放在棧內存中,供變量的引用
②建立一個變量
③讓變量和以前建立的堆內存地址進行關聯
(7)function func(a){....}
①建立值:
1)開闢一個 堆內存(heap),每個堆內存都有一個16進制的地址2)把函數體中的代碼以字符串的格式存入到堆內存中
3)把堆內存地址存放在棧內存中,供變量的引用
②建立一個變量(函數名也是變量名)
③讓變量和以前建立的堆內存地址進行關聯
(8)func(1);
函數執行
①建立一個全新執行上下文,瀏覽器開闢一塊棧內存EC(func),而且壓入執行環境棧中,才能執行
②初始化THIS
③初始化做用域鏈
④在當前執行上下文中有一個Activation Object 活動對象(AO(函數)是有瀏覽器底層語言寫的),能夠把:形參賦值、定義的變量和值存儲在這裏
⑤代碼執行
函數執行就會造成棧內存(從內存中分配一塊空間),若是內存都不銷燬釋放,很容易致使內存溢出(爆滿,卡死了)。
數據類型:基本數據類型值和引用類型值
基本類型值:結構相對簡單,直接把建立的值存儲到棧內存便可
string、boolean、number、undefined、null、symbol
引用數據類型值:結構相對複雜(一個綜合體,包含不少值),不能直接存儲在棧內存中,須要單獨開闢空間來存儲,這個空間就是堆內存
(1)對象數據類型 object普通對象{}、數組對象[]、正則對象/^$/、日期對象 new Date、數學函數對象 Math
(2)函數數據類型 function
棧內存的兩個做用:
一、提供代碼執行的環境
二、存儲基本類型值
打開瀏覽器造成的全局做用域是棧內存
函數執行造成的私有做用域是棧內存
基於ES6的let/const造成的塊級做用域是棧內存
....
那麼,棧內存釋放:
一、全局棧內存:關閉瀏覽器
二、私有棧內存:
(1)通常狀況下,函數執行完成,造成的私有棧內存就會被銷燬掉(除無限遞歸、無限循環等)
(2)一旦棧內存中的某個東西(通常都是堆內存的地址)被私有做用域之外的事物佔用了,則當前棧內存不能被當即釋放銷燬的(即:私有做用域中的私有變量等信息被保留下來了)
堆內存的做用只有一個:存儲引用數據類型的值
建立一個引用數據類型的值,就會產生一個堆內存。
若是當前建立的堆內存不被其它東西佔用了,瀏覽器會在空閒的時候,查找每個內存的引用情況,不被佔用的都會被回收釋放掉。
let obj = { id:'zhaoxiajingjing' }; let oop = obj;
此時,obj和oop都佔用着對象的堆內存,想要釋放堆內存,須要手動解除變量和值的關聯。
null:空對象指針、空對象指針、空對象指針
obj = null; oop = null;
null:空對象指針
和{}空對象
不同、不同、不同
let obj = {}; // 開闢一塊堆內存,裏面內容是空的,有16進制的地址AAAFFF000 obj = null; // 把變量obj指向空對象指針,把AAAFFF000這個堆內存釋放掉
typeof null === 'object' // true typeof {} === 'object' // true
這是瀏覽器的bug,全部存在計算機中的值都是二進制編碼存儲的,瀏覽器中的typeof方法把前三位是000的都判斷作對象。null的二進制前三位就是000,因此識別爲對象。但它不是對象。
null的數據類型是:基本類型值;null是空對象指針、空對象指針、空對象指針。
let a; console.log(a); // 輸出undefined let b = ''; console.log(b); // 輸出 '' 空字符串 let obj = {}; console.log(obj.c); // 輸出undefined console.log(obj); // 輸出 {} obj = null; console.log(obj); // 輸出 null
(1)建立了一個變量a,並未賦值,默認值是undefined
(3)建立了一個空字符串的值;建立了一個變量b;讓其與空字符串關聯。空字符串也是一個普通值。
(5)開闢一個堆內存(假設:16進制地址是AAAFFF000)裏面的目前是空的,沒有鍵值對;把堆內存地址存入棧內存中;建立了一個變量obj;讓其與棧內存的堆內存地址關聯。
(6)obj.c
獲取對象obj中的屬性c,在obj中沒有該屬性,那麼獲取到的值是undefined
(8)釋放對象obj的堆內存
找THIS:
(1)
var a = 10; function func(){ // 這裏的THIS是誰? console.log(this); } let obj = { id:'zhaoxiajingjing', name:'公號:朝霞的光影筆記', func:func };
(2)
var a = 10; function func(){ // 這裏的THIS是誰? console.log(this); } let obj = { id:'zhaoxiajingjing', name:'公號:朝霞的光影筆記', func:func }; func(); window.func(); obj.func();