個人筆記,如有錯誤煩請指正
以下面代碼的運行舉例,一行行進行運行的決議
var x = [12, 23];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x);
console.log(x);
var x = [12, 23];運行如下
- 開辟堆記憶體,創建陣列值,假設堆記憶體的地址為0x000000
- 宣告變數
x - 賦值,即將
x指向堆記憶體的地址0x000000

接著
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
運行如下
上面這段代碼是創建一個函式的程序,和創建一個變數類似:
- 都是宣告一個變數存盤值
- 步驟一樣:第一步也是先創建一個堆記憶體,里面存的是函式,這個堆記憶體有一個地址,然后把地址賦值給變數
- 宣告:方式類似函式名也算變數,當我們宣告函式
function fn(y){...}時,相當于我們宣告了一個變數,只不過值是函式,類似于var fn = function (y){...}的函式運算式,最終把一個函式作為值賦值給一個變數或者其他
所以創建一個函式,詳細的執行順序如下
- 首先開辟一個堆記憶體,存盤函式的值(假設地址為0x000001)
- 物件的值在堆記憶體當中,存盤的是它的鍵值對
- 函式的值在堆記憶體當中,存盤的是它的代碼,而且是以字串的形式存盤的
- 創建函式的時候,就宣告了它的作用域(scope),scope值是當前創建函式的時候所處的背景關系,即在哪個背景關系中創建的,作用域就是誰

- 接著宣告變數
fn,并且指向堆記憶體地址(假設為0x000001)

函式執行的步驟
fn(x);運行如下(函式執行的步驟)
- 函式執行時,永遠傳的是值,
fn(x)傳的是x的值,即x指向的0x000000堆記憶體地址 fn(0x000000)形成一個全新的私有背景關系EC(fn)- 在函式形成的新的背景關系中,生成一個私有化變數物件AO,用來存盤當前背景關系中宣告的變數(Active Object活動物件,簡稱AO,變數物件的一種,類似全域背景關系中的全域變數)

- 內部代碼執行之前發生的事
- 初始化作用域鏈scope-chain <EC(fn1),EC(G)>,鏈的兩頭是 <當前自己的私有背景關系,函式的作用域(創建函式的時候所在的背景關系)>,鏈的右側也叫當前背景關系的'上級背景關系'
- 初始化this
- 初始化argument
- 在當前背景關系中,宣告一個形參變數,并且把傳遞的實參值賦值給它
- 變數提升

- 進堆疊執行代碼
- 出堆疊釋放
函式進堆疊執行代碼的詳細步驟
接著說說上面第5步的詳細步驟
把之前創建的函式,在堆記憶體中存盤的代碼字串拿出來轉換為代碼一行一行的執行執行,
私有背景關系中代碼執行中如果遇到一個變數,首先看是否為自己的'私有變數',如果是'私有'的,則操作自己的,和外界沒有必然的關系,如果不是自己私有的,則基于作用域鏈,向其上級背景關系中查找,看是否為上級背景關系中私有的,如果也不是,繼續向上查找......一直找到EC(G)全域背景關系為止,我們把這種查找程序稱之為 作用域鏈查找機制
所以
y[0] = 100
y = [100]
y[1] = 200
是這樣的執行的:
-
y[0] = 100,y現在存盤的記憶體地址為0x000000,所以修改這個地址下的值:
-
y = [100],出現了新的物件值,所以要開辟新的堆記憶體0x000002,創建值,賦值
-
y[1] = 200,將0x000002地址對應的物件的值進行修改
-
console.log(y);這個y就是0x000002對應的值[100,200]操作的是私有變數y
fn函式至此執行完畢,
接著執行外面的console.log(x);,此時的x為全域變數物件中的x,對應的地址為0x000000,所以直接進行輸出[100,23]

如果fn執行完之后,繼續執行其他函式,同樣會經歷這樣的流程,形成新的背景關系,進堆疊執行...如果函式非常多,會一直進堆疊,占記憶體會越來越大,所以為了優化,瀏覽器會默認做出很多回識訓制
結果與總體流程
結果

總體流程圖

其他說明點
js背景關系分類
js背景關系(哪一個區域下執行)分類
- 全域背景關系EC(G)
- 函式執行形成的私有背景關系
- 塊級私有背景關系
什么是私有變數
私有變數是私有背景關系宣告的變數,包含
- 形參
- 代碼執行的時候宣告的變數
var/let/const/function...
注意與全域變數區別,沒有直接關系,但是可能會存在一些間接關系,比如下面這段代碼下全域變數x的值是0x000000,通過函式,將0x000000傳給了私有變數y,y也是0x000000
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/168072.html
標籤:其他
上一篇:jquery手風琴
下一篇:jquery類操作
