2020千峰逆戰(zhàn)班 | Python | 6-Python爬蟲技術(shù)快速上手

內(nèi)存的認(rèn)識
1.棧
棧遵循"先進(jìn)后出,后進(jìn)先出"的規(guī)則,或稱LIFO (“Last In First Out”) 規(guī)則。
如圖所示,我們只能從棧頂取出或放入乒乓球,最先放進(jìn)盒子的總是最后才能取出。
棧中"放入/取出",也可稱為"入棧/出棧"。
棧數(shù)據(jù)結(jié)構(gòu)的特點(diǎn):
1 后進(jìn)先出,先進(jìn)后出
2 出口在頂部,且僅有一個(gè)
2.堆
JS的引用數(shù)據(jù)類型(Array,Object),值的大小是不固定的,它們都保存在堆內(nèi)存中。
JS不允許直接訪問堆內(nèi)存,因此堆內(nèi)存空間中的對象我們也不能直接操作。
引用類型的值都是按引用訪問的。這里的引用就是保存在棧內(nèi)存中的一個(gè)地址,該地址與堆內(nèi)存的實(shí)際值相關(guān)聯(lián).
二、上下文
如果我們想煮一碗泡面,應(yīng)該怎么樣?
肯定是提前準(zhǔn)備好泡面,雞蛋,青菜,等想吃的時(shí)候直接下鍋煮就行.
而這里的執(zhí)行上下文就相當(dāng)于準(zhǔn)備好煮泡面的材料,只為煮的時(shí)候更加方便.
1. 這么瞧一下
js是單線程的,每當(dāng)遇到可執(zhí)行代碼時(shí),就會生成執(zhí)行上下文. 執(zhí)行上下文用于描述運(yùn)行js的環(huán)境。
當(dāng)調(diào)用函數(shù)時(shí),在執(zhí)行函數(shù)體之前的幾ms中,JS引擎會創(chuàng)建一個(gè)局部的執(zhí)行上下文。
上下文決定了他們可以訪問哪些數(shù)據(jù),以及他們的行為.
上下文在其所有代碼執(zhí)行完畢后會被銷毀,包含所有的變量和函數(shù).
全局上下文,在推出程序前才被銷毀(如關(guān)閉瀏覽器或推出程序).
js中的執(zhí)行上下文,分為三種.
1 全局環(huán)境,整個(gè)js運(yùn)行起來就進(jìn)入的環(huán)境.
2 局部環(huán)境,進(jìn)入局部函數(shù)內(nèi).
3 eval() 不在被使用.
執(zhí)行上下文就像我們要煮泡面,提前備好方便面,青菜,雞蛋啥的.想吃的時(shí)候,直接下鍋.
而不是想吃的時(shí)候再去買,那也能做好,但是速度很慢吧…
2. 全局執(zhí)行上下文
全局上下文是最外層的上下文.
對全局的變量進(jìn)行處理.
a, 將var聲明的全局變,添加給 window做屬性.
b, function 聲明的全局變量,給window做方法.
c, 給this賦值為window.
全局上下文只有唯一的一個(gè),它在瀏覽器關(guān)閉時(shí)出棧。
補(bǔ)充一點(diǎn)
a, 全局環(huán)境是最外圍的環(huán)境,根據(jù)ECMAScript實(shí)現(xiàn)所在的宿主環(huán)境不同,表示執(zhí)行環(huán)境的對象也不一樣。
b, 在web瀏覽器中,全局執(zhí)行環(huán)境被認(rèn)為是window對象,因此所有的全局變量和函數(shù)都是作為window對象的屬性和方法創(chuàng)建的。
c, 在es6中存在塊級作用域.所以let,const,class聲明的全局變量不屬于全局對象,即window的屬性。var和function聲明的變量和函數(shù)屬于全局對象的屬性.
3. 函數(shù)執(zhí)行上下文
在執(zhí)行函數(shù)前的幾毫秒中,創(chuàng)建函數(shù)的執(zhí)行上下文(存于執(zhí)行棧中).
形成上下文時(shí),需要干這么幾件事.
a, 將實(shí)參賦值給形參,且將形參添加到執(zhí)行上下文屬性中.
b, arguments賦值(實(shí)參列表),添加到執(zhí)行上下文的屬性.
c, var定義的局部變量,不賦值,添加到執(zhí)行上下文的屬性.
d, function 聲明的函數(shù),添加到執(zhí)行上下文的方法.
e, this賦值為調(diào)用函數(shù)的對象.
每個(gè)上下文中都有變量對象,上下文中的變量和函數(shù),都存儲于這個(gè)對象上.
上下文的代碼執(zhí)行時(shí),會創(chuàng)建變量對象的作用域鏈,主要決定各級上下文代碼訪問變量和函數(shù)時(shí)的順序.
代碼正在執(zhí)行的上下文變量對象,始終位于作用域鏈的最頂端.
1 函數(shù)執(zhí)行上下文被推入函數(shù)調(diào)用棧中,在函數(shù)執(zhí)行完畢后從棧頂推出??刂茩?quán)交還給之前的執(zhí)行上下文。
4. 執(zhí)行棧
執(zhí)行棧即執(zhí)行上下文棧,用于存儲代碼執(zhí)行期間創(chuàng)建的所有執(zhí)行上下文,也就是需要執(zhí)行的代碼。
JavaScript執(zhí)行在單線程上,所有的代碼都是排隊(duì)執(zhí)行。
一開始瀏覽器執(zhí)行全局的代碼時(shí),首先創(chuàng)建全局的執(zhí)行上下文,壓入執(zhí)行棧的頂部。
每當(dāng)進(jìn)入一個(gè)函數(shù)的執(zhí)行就會創(chuàng)建函數(shù)的執(zhí)行上下文,并且把它壓入執(zhí)行棧的頂部。當(dāng)前函數(shù)執(zhí)行完成后,當(dāng)前函數(shù)的執(zhí)行上下文出棧,并等待垃圾回收。
瀏覽器的 JS 執(zhí)行引擎總是訪問棧頂?shù)膱?zhí)行上下文。
function fn1(){
??fn2()
}
function fn2(){
??fn3()
}
function fn3(){
??// 用于顯示當(dāng)前執(zhí)行的代碼在堆棧中的調(diào)用路徑。
??console.trace()
}
fn1()
// 執(zhí)行結(jié)果
01-test.html:20 console.trace
fn3 @ 01-test.html:20
fn2 @ 01-test.html:17
fn1 @ 01-test.html:14
(anonymous) @ 01-test.html:22