Javascript 沒有 private , public 訪問權限設置的關鍵字,但是可以通過一定的技巧來模擬出相同的結果.
首先我們來看下面一行代碼:
var i = (1, 2, 3, 4, 5);
變量 i 最后的結果為 5.
這是逗號操作符的結果,也就是說返回最后的一個值,小括號改變了這行代碼的優先級,否則 var i = 1, 2, 3, 4, 5; 會報錯缺少標識符.
var i = (1, 2, 3, 4, function(){ return 5 * 5;});
變量 i 最后的結果為 一個函數, 返回結果 25.
這就是Javascript 的靈活之處,能夠賦值任意類型而不必提前聲明.現在我們完全可以進行如下調用:
i();
alert( i() );
來獲得返回25的一次方法調用.
我們繼續, 變量 i 是通過賦值符來獲取函數的引用的, 也就是說在等號右邊的小括號運算完后返回的最后一個結果的引用還在,雖然我們無法顯示調用,但它確實存在,如果要不通過變量的引用而調用呢?
(1, 2, 3, 4, function(){ alert(5 * 5);})()
上面的代碼執行后,彈出一個消息框,顯示25.
為了顯示方便,我將上個例子的函數改為彈出消息框了.
兩對小括號 () (); 前面一對表示返回一個結果,如果該結果為一個函數,由第二對小括號發生調用.
也就是通過前面一對括號發生匿名函數的引用,以便在下面進行引用.這就是對匿名函數的調用.
關于更多匿名函數的使用可以參考文尾的引用連接.
閉包產生的原因是因為作用域的不同,子作用域引用了父作用域的變量,而返回子作用域,父作用域按理來說執行完畢后該銷毀掉了,只是子作用域一直存在,且一直握有父作用域的引用,所以才一直保留.
來看下面的代碼
代碼如下:
function parent() {
var a = 1;
function child(){
var b = 2;
alert(a);
alert(b);
}
}
父函數 parent 中包含了一個 child 子函數,在子函數中有一個對父函數中 a 變量的引用(輸出其值).
我們來讓父函數執行完后返回其聲明的子函數
代碼如下:
function parent() {
var a = 1;
function child(){
var b = 2;
alert(a);
alert(b);
}
return child;
}
var t = parent();
t();
在10行中, 我們執行了parent 函數,返回了在函數內部聲明的函數 child,這時變量 t 持有該返回對象(此時是一個可以執行的函數)的引用,在11行代碼中我們調用了它.結果分別輸出了 1 和 2.
注意,輸出 2, 是因為我們在子函數體內聲明了一個變量,而輸出 1, 我們在該函數體內并沒有相應的定義變量 a ,而是發生了對父函數里的變量的引用,也就是說引用了父作用域的變量.
而此時又能能夠完成輸出的,也就是說變量 a 還存在.可是我們無法直接對其引用 (比如 parent.a),因為函數已經執行完畢,沒有了其相應的引用,我們只能通過所返回的子函數的引用來進行訪問.