匿名函數:沒有名字的函數;
閉包:可存取一個函數作用域裡的變數的函數;
一 匿名函數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function box(){
return 'Lee' ;
}
box();
function (){
return 'Lee' ;
}
( function (name){
console.log(name);
})( "Lee" );
var box = function (){
return 'Lee' ;
};
console.log(box());
function box(){
return function (name){
return name;
};
};
console.log(box()( "Lee" ));
|
登入後複製
二 閉包
閉包:有權存取另一個函數作用域中的變數的函數;
建立閉包的常見方式:在一個函數內部建立另一個函數;透過另一個函數存取這個函數的局部變數;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function box(){
var user = 'Lee' ;
return function (){
return user;
};
}
console.log(box()());
var b = box();
console.log(b());
|
登入後複製
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var age = 100;
function box(){
age++;
};
box();
console.log(age);
box();
console.log(age);
function box(){
var age = 100;
age++;
return age;
}
console.log(box());
console.log(box());
function box(){
var age = 100;
return function (){
age++;
return age;
};
}
var b = box();
console.log(b());
console.log(b());
|
登入後複製
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | function box(){
var arr = [];
for ( var i=0; i<5; i++){
arr[i] = function (){
return i;
};
};
return arr;
}
var b = box();
console.log(b.length);
for ( var i=0; i<b.length; i++){
console.log(box()[i]());
}
function box(){
var arr = [];
for ( var i=0; i<5; i++){
arr[i] = ( function (num){
return num;
})(i);
}
return arr;
}
var b = box();
for ( var i = 0; i < b.length; i++) {
console.log(b[i]);
};
function box(){
var arr = [];
for ( var i=0; i<5; i++){
arr[i] = ( function (num){
return function (){
return num;
}
})(i);
}
return arr;
}
var b = box();
for ( var i = 0; i < b.length; i++) {
console.log(b[i]());
};
|
登入後複製
三 this物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var user = 'Window' ;
var obj = {
user: 'Object' ,
getUserFunction: function (){
return function (){
return this.user;
};
}
};
console.log(obj.getUserFunction()());
console.log(obj.getUserFunction().call(obj));
getUserFunction: function (){
var that = this;
return function (){
return that.user;
}
}
console.log(obj.getUserFunction()());
|
登入後複製
四 記憶體洩漏
1 2 3 4 5 6 7 8 9 10 11 12 | function box(){
var oDiv = document.getElementById( 'oDiv' );
oDiv.onclick = function (){
alert(oDiv.innerHTML);
};
oDiv = null;
}
box();
|
登入後複製
五 模仿區塊級作用域(定義並立即呼叫一個匿名函數)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | function box( count ){
for ( var i=0; i< count ; i++){}
console.log(i);
}
box(2);
function box( count ){
for ( var i=0; i< count ; i++){}
var i;
console.log(i);
}
box(2);
( function (){
})();
function box( count ){
( function (){
for ( var i=0; i< count ; i++){}
})();
console.log(i);
}
box(2);
( function (){
var box = [1,2,3,4];
console.log(box);
})();
console.log(box);
|
登入後複製
六 私有變數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | function box(){
var age = 100;
}
function Box(){
var age = 100;
function run(){
return '运行中...' ;
};
this.get = function (){
return age+run();
};
}
var box = new Box();
console.log(box.get());
function Person(name){
var user = name;
this.getUser = function (){
return user;
};
this.setUser = function (name){
user = name;
}
}
var p = new Person( 'Lee' );
console.log(p.getUser());
console.log(p.setUser( 'Jack' ));
console.log(p.getUser());
|
登入後複製
七 靜態私有變數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ( function (){
var age = 100;
function run(){
return '运行中...' ;
};
Box = function (){};
Box.prototype.go = function (){
return age+run();
};
})();
var box = new Box();
console.log(box.go());
( function (){
var user = "" ;
Person = function (value){
user = value;
};
Person.prototype.getUser = function (){
return user;
};
Person.prototype.setUser = function (value){
user = value;
}
})();
var person = new Person();
person.setUser( 'Lee' );
console.log(person.getUser());
|
登入後複製
八 模組模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | var box = {
age:100,
run: function (){
return '运行中...' ;
};
};
var box = function (){
var age = 100;
function run(){
return '运行中...' ;
}
return {
go: function (){
return age+run();
}
};
}();
var box = function (){
var age = 100;
function run(){
return '运行中...' ;
}
var obj = {
go: function (){
return age+run();
}
};
return obj;
}();
function Desk(){};
var box = function (){
var age = 100;
function run(){
return '运行中...' ;
};
var desk = new Desk();
desk.go = function (){
return age+run();
};
return desk;
}();
console.log(box.go());
|
登入後複製
九 小結
在JavaScript程式設計中,函數表達式是一種非常有用的技術;使用函數表達式可以無須對函數命名,從而實現動態程式設計;
1.函數表達式
函數表達式不同於函數宣告;函數宣告要求有名字,但函數表達式不需要;
沒有名字的函數表達式叫做匿名函數;2.閉包
當在函數內部定義了其他函數時,就創建了閉包.閉包有權訪問包含函數內部的所有變數;原理如下:
在後台執行環境中,閉包的作用域鏈包含著它自己的作用域、包含函數的作用域和全域作用域;
通常,函數的作用域及其所有變數都會在函數執行結束後被銷毀;
但是,當函數回傳了一個閉包時,這個函數的作用域將會一直在記憶體中保存到閉包不存在為止;3.區塊級作用域
使用閉包可以在JavaScript中模仿區塊級作用域(JavaScript本身沒有區塊級作用域的概念);重點如下:
建立並立即呼叫一個函數,這樣既可以執行其中的程式碼,又不會在記憶體中留下對該函數的引用;
結果就是函數內部的所有變數都會立即被銷毀--除非將某些變數賦值給了包含作用域(即外部作用域)中的變數;4.私有變數
閉包也可以用於在物件中建立私有變數,要點如下:
即使JavaScript中沒有真是的私有物件屬性的概念,但是可以使用閉包來實現公有方法,而透過公有方法可以存取包含作用域中定義的變數;
可以使用建構函式模式、原型模式來實作自訂類型的特權方法,也可以使用模組模式來實作單例的特權方法;