javaScript变量、作用域链
變量
JavaScript 變量松散類型的本質(zhì),決定了它只是在特定時(shí)間用于保存特定值的一個(gè)名字而已。
變量分為基礎(chǔ)類型值和引用類型值;
基本類型值指的是 簡(jiǎn)單的數(shù)據(jù)段(Undefined、Null、Boolean、Number 和 String),而引用類型值指那些可能由多個(gè)值構(gòu)成的對(duì)象。
引用類型的值是保存在內(nèi)存中的對(duì)象。與其他語言不同,JavaScript 不允許直接訪問內(nèi)存中的位置, 也就是說不能直接操作對(duì)象的內(nèi)存空間。在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。 為此,引用類型的值是按引用訪問的
var obj1 = new Object();
作用域鏈
1.執(zhí)行環(huán)境
執(zhí)行環(huán)境(execution context,為簡(jiǎn)單起見,有時(shí)也稱為“環(huán)境”)定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為。
每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí),函數(shù)的環(huán)境就會(huì)被推入一個(gè)環(huán)境棧中。 而在函數(shù)執(zhí)行之后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。ECMAScript 程序中的執(zhí)行流 正是由這個(gè)方便的機(jī)制控制著。
全局執(zhí)行環(huán)境是最外層環(huán)境,web開發(fā)中通常認(rèn)為是window;某個(gè)執(zhí)行環(huán)境中所有代碼執(zhí)行完畢后,該環(huán)境將被銷毀,保存在其中的變量和函數(shù)也將同時(shí)被銷毀
2.當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈(scope chain)。作用域鏈的用途,是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。當(dāng)前的執(zhí)行環(huán)境就是作用域的最前端,標(biāo)識(shí)符解析是沿著作用域鏈最前端向后回溯,直到找到標(biāo)志符
3.當(dāng)某個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境(execution context)及相應(yīng)的作用域鏈。 然后,使用 arguments 和其他命名參數(shù)的值來初始化函數(shù)的活動(dòng)對(duì)象(activation object)。
閉包
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。
無論什么時(shí)候在函數(shù)中訪問一個(gè)變量時(shí),就會(huì)從作用域鏈中搜索具有相應(yīng)名字的變量。一般來講, 當(dāng)函數(shù)執(zhí)行完畢后,局部活動(dòng)對(duì)象就會(huì)被銷毀,內(nèi)存中僅保存全局作用域(全局執(zhí)行環(huán)境的變量對(duì)象)。 但是,閉包的情況又有所不同。
外部函數(shù)執(zhí)行結(jié)束后,執(zhí)行環(huán)境就會(huì)在作用域鏈中銷毀,但是由于閉包函數(shù)的局部作用域鏈仍在使用其活動(dòng)對(duì)象,所以閉包函數(shù)被銷毀時(shí)外部活動(dòng)環(huán)境才能被銷毀。
由于閉包會(huì)攜帶包含它的函數(shù)的作用域,因此會(huì)比其他函數(shù)占用更多的內(nèi)存。
this
1.(默認(rèn)綁定)普通函數(shù)調(diào)用;this指向window
在嚴(yán)格模式下(strict mode),全局對(duì)象將無法使用默認(rèn)綁定,即執(zhí)行會(huì)報(bào)undefined的錯(cuò)誤
2.(隱式綁定)作為對(duì)象方法調(diào)用;this指向調(diào)用對(duì)象
3.作為構(gòu)造函數(shù)調(diào)用,this 指代實(shí)例對(duì)象
4.call() 和 apply()
主要是通過改變對(duì)象的prototype關(guān)聯(lián)對(duì)象。具體使用上,可以通過這兩個(gè)方法call(…)或apply(…)來實(shí)現(xiàn)(大多數(shù)函數(shù)及自己創(chuàng)建的函數(shù)默認(rèn)都提供這兩個(gè)方法)call與apply是同樣的作用,區(qū)別只是其他參數(shù)的設(shè)置上,
apply:調(diào)用一個(gè)對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。例如:B.apply(A, arguments);即A對(duì)象應(yīng)用B對(duì)象的方法。
call:調(diào)用一個(gè)對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。例如:B.call(A, args1,args2);即A對(duì)象調(diào)用B對(duì)象的方法。
總結(jié)
以上是生活随笔為你收集整理的javaScript变量、作用域链的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 管理之善,在于让员工有机会试错
- 下一篇: 前端框架Vue、angular、Reac