作用域 執行環境 閉包(四)

2021-09-28 12:41:06 字數 2653 閱讀 1743

上一期我們已經介紹了閉包,由於閉包可以延長函式內部的變數的生存週期,因此我們可以將不需要暴露在全域性的變數封裝成函式的內部變數,從而避免**汙染。

譬如要實現乙個簡單的累加器,為了儲存每次累加的結果,因此宣告了乙個全域性變數total,**如下:

var total=0;

function add(t)

total=2;

add(3);        //顯示5

add(5);        //顯示10

add(1);        //顯示11

但是在實際開發中,應盡量避免全域性變數,因為全域性變數可以在**的任何地方被呼叫,假設在其他地方,不小心更改了total的值的話,我們這個累加器就會出問題了。由於total值是只供函式add()使用的,因此希望total能被封閉在函式add()的內部,這樣,就無法從外部來改寫它了,我們使用閉包來實現,**如下:

function add(s)

}var a=add(2);

a(3);        //顯示5

a(5);        //顯示10

a(1);        //顯示11

通過閉包,將變數total封閉在函式add()中,外部無法訪問到,這樣就避免了被其他**隨意改寫的可能性。

由於閉包會將封閉在函式內部的區域性變數賦予類似於全域性變數的效果,因此在有些場景下需要特別注意,尤其是涉及到迴圈遍歷,來看以下**:

function createarray()}}

這是乙個建立陣列陣列的函式,從表面上看,每個函式應該都返回自己的索引值,因此建立的陣列中,每個元素應該包含如下函式:

result[0]:function()

result[1]:function()

result[2]:function()

但是實際上,陣列中的每個元素只是包含:function(),也就是說,當該函式執行完畢後,返回的是這樣乙個陣列:

,

function(),

function()

}

而變數i由於存在於乙個返回函式中,形成了閉包,所以當createarray()執行完畢後,其執行環境不會被銷毀,變數i得以保留,並且其值為3(這點很重要)。

因此,當我們使用createarray()來建立陣列時,得到的效果就不是我們的預期,彈出的都為「3」:

var a=createarray();

for(var z=0;z

實際上該**無非就是重複執行三遍以下**:

alert(function()());

那麼為了達到我們的預期,應該將createarray()函式做如下修改:

function createarray();

}(i)}}

分析以上**,我們將乙個自執行函式返回給了陣列元素,在賦值的時候,變數z就是在賦值的那個時刻的i值,那麼返回的陣列中的元素便包含我們預期的函式:

result[0]:function()

result[1]:function()

result[2]:function()

再一次執行以下**,顯示就正常了:

var a=createarray();

for(var z=0;z

一定要注意的是,我們是把乙個函式賦予了陣列中的元素,而不是單個的值。因為在實際的應用中,返回函式的話,我們就可以在函式內做更多的事情。

看以下的實現,html有四個p標籤和4個div標籤,當單擊div標籤時相應的p標籤更改顏色,請注意這是乙個面試中非常容易遇到的題目,**如下:

p1p2

p3p4

div1

div2

div3

div4

如果直接寫成以下**的話,那麼無論你單擊哪個div,程式總是會報錯,因為此時i的值為4,所以document.getelementsbytagname("p")[4]這個元素並不存在,導致引用錯誤。

for(var i=0;i

最後我們要注意的是當需要返回函式內部的多個變數時,便不能採用返回匿名函式的方式了,可以採用以下的形式:

function setpepole(),

getage:function()} }

var a=setpepole();

alert(a.getname());     //顯示「李四」

alert(a.getage());      //顯示31

閉包系列就到此全部結束了!

更多專業前端知識,請上

【猿2048】www.mk2048.com

執行環境 作用域鏈及閉包

執行環境 execution context 定義了變數或函式有權訪問的其他資料,決定了他們各自的行為。每個執行環境都有乙個與之關聯的變數物件 variable object 環境中定義的所有變數 形參和函式宣告都儲存在這個物件中。編碼時無法訪問這個變數物件,解析器在處理資料時會在後台使用。在web...

作用域 閉包

1.js執行順序 語法分析 預編譯 先生成go物件 1.函式執行生成ao物件 2.形參和變數作為ao物件的鍵名,鍵值是undefined 3.實參賦值給形參 4.在函式中找到函式宣告,把函式作為ao物件的屬性名,屬性值為函式體 執行js 作用域 變數作用範圍 1.作用域 變數作用範圍 1 函式作用域...

作用域,閉包,作用域鏈

一,作用域 變數在宣告它的函式及該函式所巢狀的任意函式是有定義的 例var num 2 function fun fun 二,作用域鏈 多個函式巢狀在一起,多個作用域相互巢狀,這是作用域鏈 var num 1 function fun function fun2 fun1 fun2 fun 訪問原則...