私人会员

从技术上讲,JavaScript 不支持私有成员作为语言功能。隐私 - 由道格拉斯·克罗克福德(Douglas Crockford)描述 - 通过闭包(保留的函数范围)进行模拟,闭包(每个实例化函数的每个实例化调用都将生成)。

Queue 示例演示了如何使用构造函数,通过特权方法保留本地状态并使其可访问。

class Queue {

  constructor () {                    // - does generate a closure with each instantiation.

    const list = [];                  // - local state ("private member").

    this.enqueue = function (type) {  // - privileged public method
                                      //   accessing the local state
      list.push(type);                //   "writing" alike.
      return type;
    };
    this.dequeue = function () {      // - privileged public method
                                      //   accessing the local state
      return list.shift();            //   "reading / writing" alike.
    };
  }
}

var q = new Queue;            //
                              //
q.enqueue(9);                 // ... first in ...
q.enqueue(8);                 //
q.enqueue(7);                 //
                              //
console.log(q.dequeue());     // 9 ... first out.
console.log(q.dequeue());     // 8
console.log(q.dequeue());     // 7
console.log(q);               // {}
console.log(Object.keys(q));  // ["enqueue","dequeue"]

对于 Queue 类型的每个实例化,构造函数都会生成一个闭包。

因此,Queue 类型自己的方法 enqueuedequeue(参见 Object.keys(q))仍然可以访问 list,它继续生活在其建造时保存的封闭范围内。

利用这种模式 - 通过特权公共方法模拟私有成员 - 应该记住,对于每个实例,每个自己的属性方法都会消耗额外的内存 (因为它是无法共享/重用的代码)。对于将要存储在这种闭包中的状态的数量/大小也是如此。