首页 > js学习 > js基础知识 > javascript中的闭包②
2016
12-16

javascript中的闭包②

模仿块级作用域:JavaScript没有块级作用域的概念,这个可以用下面的示例证明:

function box() {

for (var i=0; i<3; i++) {}

alert(i); //3,i不会因为离开了for块就失效

}

JavaScript不会提醒你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见(如果初始化了,当然还会执行的)。使用模仿块级作用域(私有作用域)可避免这个问题

function box() {

(function () {

for (var i = 0; i<3; i++) {}//这里for语句是处于块级作用域

})();

alert(i); //报错,无法访问

}

使用了块级作用域(私有作用域)后,匿名函数中定义的任何变量,都会在执行结束时被销毁。这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。一般来说,我们都应该尽可能少向全局作用域中添加变量和函数。在大型项目中,多人开发的时候,过多的全局变量和函数很容易导致命名冲突,引起灾难性的后果。如果采用块级作用域(私有作用域),每个开发者既可以使用自己的变量,又不必担心搞乱全局作用域。

全局作用域中使用块级作用域可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。只要函数执行完毕,就可以立即销毁其作用域链了。

私有变量

JavaScript没有私有属性的概念;所有的对象属性都是公有的。不过,却有一个私有变量的概念。任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。

function box(){var age = 100;}//age为私有变量,外部无法访问

通过函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量。而利用这一点,可以创建用于访问私有变量的公有方法。

function Box() {

var age = 100; //私有变量

function run() {return '运行中...';}; //私有函数

this.get = function () {return age + run();};//对外公共的特权方法,对外接口

}

var box = new Box();

alert(box.get());

可以通过构造方法传参来访问私有变量。

function Person(value) {

var user = value; //这句其实可以省略

this.getUser = function () {return user;};

this.setUser = function (value){user = value;};

}

但是对象的方法,在多次调用的时候,会多次创建。可以使用静态私有变量来避免这个问题。

静态私有变量:通过块级作用域(私有作用域)中定义私有变量或函数,同样可以创建对外公共的特权方法。

(function () {

var age = 100;

function run() {return '运行中...';}

Box = function () {}; //构造方法,不用var关键词定义则该变量即使在私有作用域中也转变为全局变量

Box.prototype.go = function () {return age + run();};//原型方法

})();

var box = new Box();

alert(box.go());

上面的对象声明,采用的是Box = function () {} 而不是function Box() {} 因为如果用后面这种,就变成私有函数了,无法在全局访问到了,所以使用了前面这种。

(function () {

var user = '';

Person = function (value) { user = value;};

Person.prototype.getUser = function () {return user;};

Person.prototype.setUser = function (value) {user = value;}

})();

使用了prototype导致方法共享了,而user也就变成静态属性了。(所谓静态属性,即共享于不同对象中的属性)。

模块模式:之前采用的都是构造函数的方式来创建私有变量和特权方法。那么对象字面量方式就采用模块模式来创建。

var box = { //字面量对象,也是单例对象

age : 100, //这是公有属性,将要改成私有

run : function () {return '运行中...';};//这时公有函数,将要改成私有

};

私有化变量和函数:

var box = function () {

var age = 100;

function run() {return '运行中...';}

return {go : function () {return age + run();}};//直接返回对象

}();

字面量的对象声明,其实在设计模式中可以看作是一种单例模式,所谓单例模式,就是永远保持对象的一个实例。

增强的模块模式,这种模式适合返回自定义对象,也就是构造函数。

function Desk() {};

var box = function () {

var age = 100;

function run() {return '运行中...';}

var desk = new Desk(); //可以实例化特定的对象

desk.go = function () {return age + run();};

return desk;

}();

alert(box.go());

最后编辑:
作者:qingheluo
这个作者貌似有点懒,什么都没有留下。