摘要:所以,全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個(gè)對象。搜索過程從作用域鏈的最前端開始,逐級向后回溯,直到找到標(biāo)識符為止。查詢標(biāo)識符搜索過程就是沿作用域鏈向上查詢的過程。
執(zhí)行環(huán)境
執(zhí)行環(huán)境就是“環(huán)境”,是js中最重要的概念。執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù)。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之相關(guān)的變量對象(我們編寫的代碼無法訪問這個(gè)對象)。
全局執(zhí)行環(huán)境(是最外圍的執(zhí)行環(huán)境。在Web瀏覽器中,全局執(zhí)行環(huán)境是Window對象。某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后,該環(huán)境會被銷毀;全局執(zhí)行環(huán)境則直到應(yīng)用程序退出,如關(guān)閉網(wǎng)頁或?yàn)g覽器時(shí)才會被銷毀。環(huán)境被銷毀時(shí),保存在其中的所有變量和函數(shù)定義也都會被銷毀。)
執(zhí)行環(huán)境(當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí),函數(shù)的環(huán)境會被推入一個(gè)環(huán)境棧中。當(dāng)函數(shù)執(zhí)行之后,環(huán)境棧將其彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。)
作用域鏈(當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會創(chuàng)建變量對象的一個(gè)作用域鏈。其用途是保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。一個(gè)包含環(huán)境的變量對象到另一個(gè)包含環(huán)境的變量對象,最后到全局執(zhí)行環(huán)境的變量對象。所以,全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個(gè)對象。)
標(biāo)識符解析標(biāo)識符解析是沿著作用域鏈一級一級地搜索標(biāo)識符的過程。搜索過程從作用域鏈的最前端開始,逐級向后回溯,直到找到標(biāo)識符為止。如:
var color = "blue"; function changeColor(){ if (color === "blue"){ color = "red"; }else { color = "blue"; } } changeColor(); document.write("Color is now " + color);
在上面的例子中,函數(shù)changeColor()的作用域鏈包含兩個(gè)對象:changeColor()函數(shù)自己的變量對象和全局環(huán)境的變量對象。(可以在函數(shù)內(nèi)部訪問變量color,就是因?yàn)榭梢栽谶@個(gè)作用域鏈中找到它。)在看另一個(gè)例子:
var color = "blue"; function changeColor(){ var anotherColor = "red"; function swapColors(){ var tempColor = anotherColor; anotherColor = color; color = tempColor; //這里可以訪問tempColor anotherColor color } //這里可以訪問anotherColor color } //這里可以訪問color changeColor();
執(zhí)行環(huán)境:3個(gè),全局環(huán)境,changeColor()的局部環(huán)境和swapColors()的局部環(huán)境。
全局環(huán)境:一個(gè)變量color 和一個(gè)函數(shù)changeColor()。
changeColor()環(huán)境:一個(gè)變量anotherColor 和一個(gè)swapColors()函數(shù)。(可以訪問全局變量中的color)
swapColors()環(huán)境:一個(gè)變量tempColor。(可以訪問全局環(huán)境中的color 和changeColor()環(huán)境中的anotherColor變量。)
swapColors()內(nèi)部可以訪問到其他兩個(gè)環(huán)境中的所有變量,因?yàn)槠渌麅蓚€(gè)環(huán)境是它的父執(zhí)行環(huán)境*
上面的例子可以用作用域鏈表示出來:(話說有沒有網(wǎng)友可以推薦下好用的圖床呀?純文本畫畫還真麻煩。)
window(全局環(huán)境) | |-color(變量) | |-changeColor()(局部環(huán)境) | |-anotherColor(變量) | |-swapColors()(局部環(huán)境) | |-tempColor(變量)
內(nèi)部環(huán)境可以通過作用連訪問所有的外部環(huán)境,但外部環(huán)境不能訪問內(nèi)部環(huán)境的任何變量和函數(shù)。就是說,每個(gè)環(huán)境都可以向上搜索作用域鏈,但任何環(huán)境都不能向下搜索作用域鏈。
延長作用域鏈雖然執(zhí)行環(huán)境的類型總共只有全局和局部(函數(shù))兩種,但是還是可以使用下面兩種辦法來延長作用域鏈。
try-catch 語句的catch 塊;
with 語句
上面這種方法就是當(dāng)執(zhí)行流進(jìn)入下列任何一個(gè)語句時(shí),作用域鏈就會得到加長。如:
function log(){ var string = "the location is: " with(location){ var url = string + href; } return url; } document.write(log()); //the location is: ... Volumes/TOSHIBA/project/tester/repetition.html
這里面使用with 語句,可以看到return url 語句可以訪問到with 語句中的url 變量。再看下面的例子:
function log(){ var string = "the location is: " function href(){ var url = string + location.href; } return url; } document.write(log()); // ReferenceError: Can"t find variable: url
如果是普通的function 函數(shù)則不能訪問url 變量。
另外,在IE8 中,即使是在catch 塊的外部也可以訪問到錯(cuò)誤對象。IE9 修復(fù)了這個(gè)問題。
沒有塊級作用域JavaScript 不像C 語言中,由花括號封閉的代碼塊都有自己的作用域。JavaScript 沒有塊級作用域。如:
if (true){ var color = "blue"; } document.write(color); //"blue"
花括號以外的地方仍然可以訪問話括號內(nèi)的變量。
尤其應(yīng)該在for 循環(huán)中注意這個(gè)特性:
for (var i = 0; i < 5; i ++){ var count = i + i; } document.write(count); //8聲明變量
如果初始化變量時(shí)沒有使用var 聲明,該變量會被添加到全局環(huán)境中去。如:
function count(x,y){ var result = x + y; } count(1,2); document.write(result); // ReferenceError: Can"t find variable: result function count(x,y){ result = x + y; } count(1,2); document.write(result); //3
在編寫代碼的過程中,不聲明而直接初始化變量是一個(gè)常見的錯(cuò)誤做法。很可能會導(dǎo)致以外。建議在初始化變量之前,一定要先聲明。在嚴(yán)格模式下,初始化未經(jīng)聲明的變量會導(dǎo)致錯(cuò)誤。
查詢標(biāo)識符搜索過程就是沿作用域鏈向上查詢的過程。如:
var result = 1; function func(){ document.write(result); } func(); //1
如果局部環(huán)境中存在著同名標(biāo)識符,就不會使用位于父環(huán)境中的標(biāo)識符。如:
var result = 2; function func(){ var result = 1; document.write(result); } func(); //1 document.write(window.result); //2 或者直接用下面的代碼返回最初的result document.write(result);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86162.html
摘要:函數(shù)節(jié)流使得一定時(shí)間內(nèi)只觸發(fā)一次函數(shù)。區(qū)別函數(shù)節(jié)流不管事件觸發(fā)有多頻繁,都會保證在規(guī)定時(shí)間內(nèi)一定會執(zhí)行一次真正的事件處理函數(shù),而函數(shù)防抖只是在最后一次事件后才觸發(fā)一次函數(shù)。這樣的場景,就適合用節(jié)流技術(shù)來實(shí)現(xiàn)。需要注意一點(diǎn),服務(wù)端也要支持。 原文 https://github.com/Ritr/mark/... js 閉包要理解閉包,首先要知道javascript的作用域。通常ja...
摘要:深入理解原型和閉包王福朋博客園深入理解原型和閉包一切都是對象原文鏈接本文要點(diǎn)一切引用類型都是對象,對象是屬性的集合。每個(gè)對象都有一個(gè),可稱為隱式原型。另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫規(guī)則約定。 深入理解javascript原型和閉包 王福朋 - 博客園 —— 《 深入理解javascript原型和閉包》 1. 一切都是對象 原文鏈接:http://www.cnblogs.com...
摘要:類型每個(gè)函數(shù)都是類型的實(shí)例。如以上代碼可行,是因?yàn)樵诖a開始值錢,解析器就已經(jīng)通過一個(gè)名為函數(shù)聲明提升的過程,讀取并將函數(shù)聲明添加到執(zhí)行環(huán)境中去。也可同時(shí)使用函數(shù)聲明和函數(shù)表達(dá)式,但在瀏覽器中會出錯(cuò)。 Function 類型 每個(gè)函數(shù)都是Function 類型的實(shí)例。函數(shù)名實(shí)際上就是一個(gè)指向函數(shù)對象的指針,不會與某個(gè)函數(shù)綁定。 函數(shù)聲明方式創(chuàng)建Function,語法如下: functi...
摘要:如他返回的對象是。方法,這個(gè)方法用于確定文檔是否獲得了焦點(diǎn)。另外,需要注意的是,該屬性插入元素并不會執(zhí)行其中的腳本。在中,方法接收一個(gè)字符串,返回一個(gè)經(jīng)過無害處理后的版本。屬性同樣的,在讀模式下返回調(diào)用它的元素及所有子節(jié)點(diǎn)的標(biāo)簽。 與類相關(guān)的擴(kuò)充 getElementsByClassName()方法 接收一個(gè)參數(shù),即一個(gè)或多個(gè)類名的字符串。如: console.log(documen...
閱讀 1026·2021-11-22 13:52
閱讀 936·2019-08-30 15:44
閱讀 580·2019-08-30 15:43
閱讀 2436·2019-08-30 12:52
閱讀 3484·2019-08-29 16:16
閱讀 645·2019-08-29 13:05
閱讀 2951·2019-08-26 18:36
閱讀 2006·2019-08-26 13:46