JavaScript使用闭包

封装私有变量

许多编程语言使用私有变量,这些私有变量是对外部隐藏的对象属性。这是非常有用的一种特性,因为当通过其他代码访问这些变量时,我们不希望对象的实现细节对用户造成过度负荷。遗憾的是,原生JavaScript不支持私有变量。但是,通过使用闭包,我们可以实现很接近的、可接受的私有变量。

console.log("-----------------------使用闭包模拟私有变量---------------------------------");

//在构造函数内部声明一个变量,因为所声明的变量的作用域局限于构造函数内部,所以他是一个"私有"变量。我们使用该变量统计次数。
//定义NinjaTest构造函数
function NinjaTest() {
  var feints = 0;
  //创建用于访问计数变量feints的方法。由于在构造函数外部的代码是无法访问feints变量的。
  this.getFeints = function () {
    return feints;
  };
  //为feints变量声明一个累加方法。由于feints是私有变量,在外部是无法累加的,累加过程则被限制在我们提供的方法中
  this.feint = function () {
    feints++;
  };
}

var ninjaTest1 = new NinjaTest();
//通过调用feint方法,通过该方法增加feints的值
ninjaTest1.feint();


//验证我们无法获取该变量值
if (ninjaTest1.feints === undefined) {
  console.log("And the private data is inaccessible to us.");
}

//虽然我们无法直接对feints变量赋值,但是我们仍然能够通过getFeints方法操作该变量的值。
if (ninjaTest1.getFeints() === 1) {
  console.log("We are able to access the internal feint count.");
}

//当我们通过ninjaTest构造函数创建一个新的ninjaTest2实例时,ninjaTest2对象则具有自己的私有的feints变量。
var ninjaTest2 = new NinjaTest();
if (ninjaTest2.getFeints() === 0) {
  console.log("The second ninjaTest object gets its own feints variable.");
}

 

上述代码中,我们创建了一个NinjaTest构造器,通过在函数上使用关键字new时,就会创建一个新的对象实例,此时调用构造函数,将新的对象作为它的上下文。所以,函数内的this将指向新的实例化对象。

在构造器内部,我们定义了一个变量feints用于保存状态。由于JavaScript作用域规则的限制,因此只能在构造器内部访问该变量。为了让作用域外部的代码能够访问该变量,我们定义了访问该变量的方法getFeints。该方法可以读取私有变量,但不能够改写私有变量。(只读访问的方法通常称为'getter')。

//定义NinjaTest构造函数

function NinjaTest() {

var feints = 0;

//创建用于访问计数变量feints的方法。由于在构造函数外部的代码是无法访问feints变量的。

this.getFeints = function () {

return feints;

};

//为feints变量声明一个累加方法。由于feints是私有变量,在外部是无法累加的,累加过程则被限制在我们提供的方法中

this.feint = function () {

feints++;

};

}

接下来来创建增量方法feint,用于控制私有变量的值。在真实的应用程序中,该方法可能是一些业务逻辑的处理方法,但在上述代码中只是增加变量feints的值。

var ninjaTest1 = new NinjaTest();

//通过调用feint方法,通过该方法增加feints的值

ninjaTest1.feint();

结论:我们可以通过闭包内部方法获取私有变量的值,但是不能直接访问私有变量。这有效地阻止了读私有变量不可控的修改,这与真实的面向对象语言总的私有变量一样。

 

 

 

在构造器中隐藏变量,使其在外部作用域中不可访问,但是可在闭包内部进行访问。

1.通过变量ninjaTest,对象实例是可见的。

2.因为feint方法在闭包内部,因此可以访问变量feints。

3.在闭包外部,我们无法直接访问变量feints。

 

通过使用闭包,可以通过方法对ninjaTest的状态进行维护,而不允许用户直接访问——这是因为闭包内部的变量可以通过闭包内的方法访问,构造器外部的代码则不能访问闭包内部的变量。

 

参考《JavaScript忍者秘籍》

猜你喜欢

转载自blog.csdn.net/zhangying1994/article/details/85054394