一、作用域
js中函式的作用域就是乙個函式可訪問的變數範圍,以一對大括號為乙個圈,如下圖:
函式b可以訪問a中的變數,c也可以訪問a中的變數,但b與c之間無法相互訪問內部的變數(當然你也可以通過一些特殊的方式實現,如函式相互呼叫通過引數傳遞內部變數等等…),a中也無法訪問b、c中的引數(別把a當做js檔案,它也可以是乙個函式,js中是允許在函式中定義函式的哦)。
二、閉包
閉包其實就是在函式內部定義另乙個函式以實現函式之間變數的傳遞(就是把c放到b裡去,此時c及c能訪問到的變數就形成了乙個閉包),這麼做的目的是什麼呢?它能減少全域性變數的建立、函式間引數值的傳遞,並且具備更好的封裝性,舉個例子:
function getadd(base)
} var add= getadd(10);
console.log(add(5));
console.log(add(3));
這裡定義了乙個getadd方法,他需要傳入乙個基數,會返回乙個函式,呼叫後獲得add方法,第一次列印15,第二次列印13,而普通的方法要麼需要定義全域性變數,要麼每次傳入兩個引數,在邏輯複雜,全域性變數十分多的情況下,可以採用這種方式以減小變數命名衝突的情況(畢竟衝突了編譯器也不會報錯,很難找到錯誤的地方)。閉包還有一些常用用法,如匿名函式自呼叫,將匿名函式中的物件作為屬性新增到window物件上:
(function()
})();
console.log(add(5));
這裡有乙個直接被呼叫的匿名函式,其內部定義了乙個add函式並作為屬性新增到了window物件
上(方法也是可以作為屬性新增到物件上的,相當於在物件內定義了乙個函式,js是能在執行時動態為乙個物件新增方法的)所以在最後一行可以直接呼叫add方法,當然你也可以在匿名函式呼叫前建立乙個物件:
var obj = {};
此時該物件一定要要乙個值,哪怕是「{}」空的(畢竟undefined可不是乙個新增屬性的物件),然後在匿名函式中將window改為obj就行了,呼叫時這樣呼叫:
console.log(obj.add(5));
小案例:編寫乙個可以統計創造出的物件數量的構造器
(function()
function person(_name,_age)
window.person = person;
})();
var p = new person();
console.log(p.getcount());//1
new person();
new person();
console.log(p.getcount());//3
這裡將本應該是全域性變數的count通過閉包進行了封裝,通過這樣的方式建立全域性函式比在物件定義中新增函式效率更高,因為所有物件使用的都是同乙個函式。 Javascript變數作用域
1.變數作用域是什麼鬼?2.全域性變數 全域性變數擁有全域性作用域 作用範圍在整個頁面中 在 的任何地方都有定義。擁有全域性作用域的情形 1 宣告在函式外部的變數。eg var a 全域性變數 function b 2 宣告變數時,缺少關鍵字var。eg function b 函式引數的變數 fun...
javascript作用域鏈
首先我們來看一段 然後通過分析這段 來說明作用域鏈的這個問題,如下 console.log total var total 0 function fn num1,num2 fn 100,200 console.log total 複製 這段 輸出的結果為 undefined undefined 30...
javascript 詞法作用域
定義在詞法階段的作用域,開始時,編譯器做語法分析的時候,確認js裡各個詞法所在的作用域。js裡只有全域性作用域和函式作用域,這裡簡單介紹下js的作用域。看下面 var a 1 var b 0 function foo foo console.log a 11 在foo函式裡,在console.log...