JavaScript中的私有成员

2019-06-03 19:36:41丽君

function Container(param) {
  function dec() {
   if (secret > 0) {
     secret -= 1;
     return true;
   } else {
     return false;
   }
  }

  this.member = param;
  var secret = 3;
  var self = this;
}

私有方法dec会检查实例变量secret,如果它大于0,自减1并返回true;如果它小于0,返回false。这样就实现了由这个架造器所创建对象的dec函数只能用三次的功能。

按惯例,我们创建了一个私有变量self。私有方法可以通过它来访问到对象本身。但这只是一种权宜之计,因为《ECMAScript Language Specification》中有一个错误,使得内部函数的this变量被设置成一个错误值。

公有方法(SharkUI.com注:即上文说的通过prototype创建的方法)是无法调用私有方法的,所以为了能使用私有方法,我们需要引入特权方法(privileged method)。

特权

一个特权方法可以访问私有变量和方法,而它本身可以被公有方法和外界访问。你可以删除或替换一个特权方法,但不能修改它,也不能强制它放弃自己的密秘(SharkUI.com注:原文如此,可能是指它的特权,关于这点请高手指教)。

特权方法是在构造器内部通过this来创建的。

function Container(param) {
  function dec() {
   if (secret > 0) {
     secret -= 1;
     return true;
   } else {
     return false;
   }
  }

  this.member = param;
  var secret = 3;
  var self = this;

  this.service = function () {
   if (dec()) {
     return self.member;
   } else {
     return null;
   }
  };
}

service是一个特权方法。前三次调用myContainer.service()将返回'abc',之后将返回null。service通过调用私有方法dec来访问私有变量secret。对于其他对象和方法来说,可以访问到service,但不能直接访问到私有的成员。

闭包

这种公有、私有和特权成员模式的存在是由于JavaScript的内在机制:闭包。这意味着一个内部函数永远可以访问它外部函数的变量和参数,即使外部函数已经返回。这是JavaScript语言非常强大的一个特性。目前还没有关于JavaScript编程的书籍展示了如何来利用它,它们甚至都没有提到这一点。

私有和特权成员只能在对象初始化的时候创建,而公有成员可以被随时添加进来。

模式

公有
function Constructor(...) {
  this.membername = value;
}
Constructor.prototype.membername = value;
私有
function Constructor(...) {
  var self = this;
  var membername = value;
  function membername(...) {...}
}

注:这句代码:

function membername(...) {...}

事实上是以下代码的简略写法

var membername = function membername(...) {...};
特权
function Constructor(...) {
  this.membername = function (...) {...};
}