闭包是指有权访问另外一个函数做用域的变量的函数。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