A. js 閉包原理
1、閉包的概念:指有權訪問另一個函數作用域中的變數的函數,一般情況就是在一個函數中包含另一個函數。
2、閉包的作用:訪問函數內部變數、保持函數在環境中一直存在,不會被垃圾回收機制處理
因為函數內部聲明 的變數是局部的,只能在函數內部訪問到,但是函數外部的變數是對函數內部可見的,這就是作用域鏈的特點了。
子級可以向父級查找變數,逐級查找,找到為止
因此我們可以在函數內部再創建一個函數,這樣對內部的函數來說,外層函數的變數都是可見的,然後我們就可以訪問到他的變數了。
3、閉包的優點:
方便調用上下文中聲明的局部變數
邏輯緊密,可以在一個函數中再創建個函數,避免了傳參的問題
4、閉包的缺點:
因為使用閉包,可以使函數在執行完後不被銷毀,保留在內存中,如果大量使用閉包就會造成內存泄露,內存消耗很大
B. 誰來解釋一下Javascript閉包的概念
閉包是可以包含自由(未綁定到特定對象)變數的代碼塊;這些變數不是在這個代碼塊內或者任何全局上下文中定義的,而是在定義代碼塊的環境中定義(局部變數)。"閉包" 一詞來源於以下兩者的結合:要執行的代碼塊(由於自由變數被包含在代碼塊中,這些自由變數以及它們引用的對象沒有被釋放)和為自由變數提供綁定的計算環境(作用域)。
簡而言之,閉包的作用就是在函數執行完並返回後,閉包使得Javascript的垃圾回收機制GC不會收回函數所佔用的資源,因為函數的內部函數的執行需要依賴函數中的變數。
一個閉包的實例:
functionCounter(start){
varcount=start;
return{
increment:function(){
count++;
},
get:function(){
returncount;
}
}
}
varfoo=Counter(4);
foo.increment();
foo.get();//5
C. js中作用域,閉包問題
這篇文章主要介紹了JavaScript中的作用域和閉包問題,是JS入門學習中的基礎知識,需要的朋友可以參考下
JavaScript的作用域以函數為界,不同的函數擁有相對獨立的作用域。函數內部可以聲明和訪問全局變數,也可以聲明局部變數(使用var關鍵字,函數的參數也是局部變數),但函數外部無法訪問內部的局部變數:
function test() {
var a = 0; // 局部變數
b = 1; // 全局變數
}
a = ?, b = ? // a為undefined,b為1
同名的局部變數會覆蓋全局變數,但本質上它們是兩個獨立的變數,一方發生變化不會影響另一方:
a = 5; // 函數外a的值為5
function test() {
var a = 4; // 函數內a的值為4
}();
a = ? // 函數外a的值仍為5,不受函數影響
一般而言,函數結束後,對函數內部變數的引用全部結束,函數內的局部變數將被回收,函數的執行環境將被清空,但是,如果以內部函數作為函數的返回結果,情況就會發生變化:
function test(i) {
var b = i * i;
return function() {
return b--;
};
}
var a = test(8);
a(); // 返回值為64, 內部變數b為63
a(); // 返回值為63, 內部變數b為62
當以內部函數作為返回值時,因為函數結束後內部變數的引用並未結束,所以函數的局部變數無法回收,函數的執行環境被保留下來,因而形成了閉包效果,可以通過該引用訪問本該被回收的內部變數。
閉包還使得函數的局部變數成為「私有」變數,只能通過返回的內部函數訪問,而無法通過其他任何手段去改變。
因此,閉包可用於維持局部變數和保護變數。
不使用閉包的情況:
var a = []; // 假設a中包含5個元素
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = function(e) {
return 'No. ' + i;
};
}
// 點擊任何一個元素,返回值都是「No. 5」,因為i最後的值
D. 如何理解閉包
定義和用法:當一個函數的返回值是另外一個函數,而返回的那個函數如果調用了其父函數內部的其它變數,如果返 回的這個函數在外部被執行,就產生了閉包。 2、表現形式:使函數外部能夠調用函數內部定義的變數。 3...
E. PHP有辦法在閉包外部得到閉包內部的變數嗎
php 有閉包函數么?好像么有吧,你可能是想問以下兩種情況
一。外部訪問類的私有變數,可以使用 __get()方法
class test{
private $b = 10;
function __get($name){
return $this->$name;
}
}
$a = new test();
echo $a->b;
二.方法內部訪問全局變數 可以使用global 關鍵字
$b = 10;
function test(){
global $b;
echo $b;
}
F. JavaScript中的閉包是用來做什麼的
閉包有兩個作用,一是外部可以讀取函數內部的變數
functionf1(){
n=999;
functionf2(){
alert(n);
}
returnf2;
}
varresult=f1();
result();//999
另一個就是讓這些變數的值始終保持在內存中
functionf1(){
varn=999;
nAdd=function(){n+=1}
functionf2(){
alert(n);
}
returnf2;
}
varresult=f1();
result();//999
nAdd();
result();//1000
在這段代碼中,result實際上就是閉包f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變數n一直保存在內存中,並沒有在f1調用後被自動清除。
為什麼會這樣呢?原因就在於f1是f2的父函數,而f2被賦給了一個全局變數,這導致f2始終在內存中,而f2的存在依賴於f1,因此f1也始終在內存中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是「nAdd=function(){n+=1}」這一行,首先在nAdd前面沒有使用var關鍵字,因此 nAdd是一個全局變數,而不是局部變數。其次,nAdd的值是一個匿名函數(anonymous function),而這個
匿名函數本身也是一個閉包,所以nAdd相當於是一個setter,可以在函數外部對函數內部的局部變數進行操作。
其應用場景就是:
函數a中i只有函數b才能訪問,而無法通過其他途徑訪問到,因此保護了i的安全性。
在內存中維持一個變數
通過保護變數的安全實現JS私有屬性和私有方法(不能被外部訪問)
私有屬性和方法在Constructor外是無法被訪問的
G. PHP有辦法在閉包外部得到閉包內部的變數嗎
這個方法很多的,最簡單的就是在類裡面聲明一個變數,然後再閉包內部把變數指定給這個類變數就可以了,還有可以藉助資料庫、session以及緩存等等。
H. 函數外部有age=12,內部函數能不能訪問到
談到JavaScript的閉包必然離不開作用域。在javascript里,作用域分為全局作用域(在任何地方都能訪問)和局部作用域(在指定的代碼片段內能訪問)。
1、局部作用域通常是函數內部作用域,在函數外部是無法直接訪問函數內部定義的局部變數。看如下代碼:
function fun () {
var age = 18;
}
console.log(age) //Uncaught ReferenceError: age is not defined 報錯,age未定義
由此可見,在fun函數外部是無法訪問函數fun內部的age變數的
2、閉包則提供了一種在局部作用域外訪問局部作用域內部變數的途徑。看如下代碼:
function fun () {
var age = 18;
function getAge () {
age++
return age
}
return getAge
}
var foo = fun()
console.log(foo()) //19 第一次運算的結果
console.log(foo()) //20 age並沒有被回收,一直存在,所以第二次運算是:19++則是20,而不是重新定義age=18
console.log(foo()) //21 age並沒有被回收,一直存在,所以第三次運算是:20++則是21,而不是重新定義age=18
我們在函數fun外部成功的獲取到了函數fun內部的局部變數age。可以看出,fun函數的返回值是一個調用了局部變數age的函數getAge,那麼在fun外部調用fun時能得到fun函數的內部函數getAge,而這個內部函數getAge是可以訪問fun內部的局部變數age的,所以我們能夠在函數fun外訪問到age。由於函數fun可在對應的作用域內調用,且調用時需要訪問它內部的局部變數age,所以fun內部的age需要一直存在,直到fun被回收。
3、閉包的應用場景
a、由於函數fun內部的age變數會一直存在,那麼可以用來做變數值的長期保存。
b、當某些變數需要限制訪問許可權,做變數保護時,就可以使用閉包,提供指定的訪問介面訪問變數。
I. 初學js,一個很簡單的問題,為什麼函數外訪問不到函數內的全局變數
原因如下:
1、函數裡面的變數不是全局變數,函數內部聲明的變數一定是局部變數,所以想要外部訪問是無法直接訪問到的,請規范全局變數和局部變數的定義。
2、外部想要訪問函數內的變數可以採用閉包來實現,代碼實例如下:
functiontest(){
varx=10;
returnfunction(){
returnx;
}
}
//調用局部變數x,報錯未定義
alert(x);
//調用
vara=test();
alert(a());
這樣可以實現外部訪問內部變數。