閉包是指有權訪問另外一個函數做用域的變量的函數。javascript
匿名函數的執行環境具備全局性。外圍函數返回的匿名函數僅僅是定義,還還沒有執行;函數內部的this對象指向函數據以執行的環境對象,當匿名函數被執行時,返回的匿名函數所處的執行環境是全局環境,故而this指向全局環境的變量對象。java
var name = "Bob"; function out() { var name = "Tom"; return function() { return this.name; } } alert(out()()); // Bob
若是function關鍵字是語句的開始,則這是一個函數聲明。若要將函數聲明轉爲函數表達式只須要用"()"括住函數聲明便可。閉包
任何在函數中定義的變量,均可以認爲是私有變量。私有變量包括函數的參數、局部變量和函數內部定義的其餘函數。函數
特權方法指有權訪問私有變量和私有函數的公有方法。this
建立私有變量的經常使用方法是構造函數模式:prototype
function Test(name) { var age = 24; this.sayName = function() { return name; }; } alert(new Test("Tom").sayName()); // Tom alert(new Test("Tom").age); // undefined
構造函數內部的age、name是私有變量,不是實例變量(this.valueName),實例方法sayName是特權方法,可以訪問name私有變量。code
爲了解決建立多個實例時會重複建立特權方法的問題,能夠:對象
(function() { var privateValue = 24; function privateFunction() { alert("Hello,world!"); } // 用匿名構造函數初始化全局對象 Obj = function(){ }; Obj.prototype.publicMethod = function() { alert(privateValue); privateFunction(); }; })(); m = new Obj(); m.publicMethod();
模塊模式是爲單例建立私有變量和特權方法。ip
所謂單例,指的就是隻有一個實例的對象。按照慣例,JavaScript以對象字面量來建立單例對象。作用域
(function() { var privateValue = 24; function privateFunction() { alert("Hello,world!"); } return { publicProperty: "public", publicMethod: function() { alert(privateValue); privateFunction(); } }; })().publicMethod();
加強模式返回的單例都是Object類型的,若是須要特定類型的單例,能夠使用加強模塊模式:
test = (function() { var privateValue = 24; function privateFunction() { alert("Hello,world!"); } Bob = new Student(); Bob.publicProperty = "public", Bob.publicMethod = function() { alert(privateValue); privateFunction(); }; return Bob; })(); function Student() { } test.publicMethod(); alert(test instanceof Student); // true