目錄javascript
使用閉包定義私有變量java
var factorial = (function f(num){ if (num <= 1){ return 1; }else { return num * f(num - 1); } });
閉包是指有權訪問另外一個函數做用域中變量的函數
建立閉包的常見方式:在一個函數內部建立另外一個函數
過分使用閉包會致使內存佔用過多,要慎重使用閉包
閉包只能取得包含函數中任何變量的最後一個值app
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; }
表面看每一個函數都返回本身的索引值,實際上每一個函數都返回10
由於每一個函數的做用域鏈中都保存着createFunctions()函數的活動對象,它們引用同一變量
能夠建立另外一個匿名函數讓閉包行爲符合預期函數
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(num){ return function(){ return num; }; }(i); } return result; }
匿名函數的執行環境具備全局性,this對象一般指向windowthis
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"The Window"
把外部做用域中的this對象保存到閉包可以訪問到的變量中prototype
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()()); //"MyObject"
若是閉包的做用域鏈保存着一個HTML元素意味着該元素將沒法被銷燬指針
function assignHandler(){ var element = document.getElementById("someElement"); element.onclick = function(){ alert(element.id); }; }
匿名函數對assignHandler()活動對象的引用,element引用次數最少是1,佔用內存沒法被回收
修改代碼解決內存泄漏問題code
function assignHandler(){ var element = document.getElementById("someElement"); var id = element.id; element.onclick = function(){ alert(id); }; element = null; }
(function(){ //這裏是塊級做用域 })();
匿名函數中定義的變量執行後銷燬
不會搞亂全局做用域component
私有變量包括函數的參數,局部變量和函數內部定義的其餘函數
特權方法:有權訪問私有變量和私有函數的公有方法成爲特權方法
靜態的,由全部實例共享的屬性
(function(){ var name = ""; Person = function(value){ name = value; }; Person.prototype.getName = function(){ return name; }; Person.prototype.setName = function (value){ name = value; }; })(); var person1 = new Person("Nicholas"); alert(person1.getName()); //"Nicholas" person1.setName("Greg"); alert(person1.getName()); //"Greg" var person2 = new Person("Michael"); alert(person1.getName()); //"Michael" alert(person2.getName()); //"Michael"
模塊模式:爲單例建立私有變量和特權方法
單例:只有一個實例的對象
JavaScript中用對象字面量的方式建立單例對象
若是建立一個對象並以某些數據對其初始化,同時還要公開一些訪問私有數據的方法,就能夠用模塊模式
function BaseComponent(){ } function OtherComponent(){ } var application = function(){ //private variables and functions var components = new Array(); //initialization components.push(new BaseComponent()); //public interface return { getComponentCount : function(){ return components.length; }, registerComponent : function(component){ if (typeof component == "object"){ components.push(component); } } }; }(); application.registerComponent(new OtherComponent()); alert(application.getComponentCount()); //2
返回對象以前加入對其加強的代碼
適合單例必須是某種類型的實例,同時還必須添加某些屬性和方法對其加以加強的狀況
function BaseComponent(){ } function OtherComponent(){ } var application = function(){ //private variables and functions var components = new Array(); //initialization components.push(new BaseComponent()); //create a local copy of application var app = new BaseComponent(); //public interface app.getComponentCount = function(){ return components.length; }; app.registerComponent = function(component){ if (typeof component == "object"){ components.push(component); } }; //return it return app; }(); alert(application instanceof BaseComponent); application.registerComponent(new OtherComponent()); alert(application.getComponentCount()); //2