如何创build共享的,特权的公共方法?

现在我的一个类的一些方法是公共的,但是可以访问私有variables(它们是特权的)。 这是因为它们是在类的构造函数中创build的,所以它们的闭包可以访问对象闭包。

但是,我想避免的是每次创build新的特权方法时的内存和性能开销。 所以我想分享他们。

有什么办法可以将特权方法放入原型?

请求示例:

function Person(age) { // age is private this.grow = function() { // grow is now public, but can access private "age" age += 1; } } dan = new Person(10); dan.grow(); dan.age; // undefined 

这工作,我有一个公共的方法“成长”,可以访问私人variables“年龄”,但成长必须重新为每个对象。

更高性能的方法是:

 function Person(age) { // age is private this.age = age; // but this.age is public } Person.prototype.grow = function() { this.age += 1; } dan = new Person(10); dan.grow(); dan.age; // 11 

这分享“成长”的方法,但现在年龄是公开的。

你可以做这样的事情(没有ES6),但我不认为这是一个好的解决scheme。

 var Person = (function () { var id = 0, data = {}, key = Math.random(); function Person(age) { var thisId = id; data[id] = age; id += 1; this.getId = function(check) { if (check !== key) { return undefined; } return thisId; }; } Person.prototype.grow = function () { var thisId = this.getId(key); data[thisId] += 1; console.log(data[thisId]); return this; }; Person.prototype.destroy = function () { var thisId = this.getId(key); data[thisId] = null; delete data[thisId]; }; return Person; }()); var dan = new Person(10); dan.grow(); console.log(dan.age); // undefined console.log(dan.getId()); // undefined 

在jsFiddle

添加@DanRedux:

 function Person(age) { this.private = {age:age}; } Person.prototype.grow = function() { this.private.age += 1; } dan = new Person(10); dan.grow(); dan.age; // undefined dan.private.age; // 11 

是的,这确实是可能的。 但是它需要一点点的诡计:

 var createTree = require("functional-red-black-tree"); var Person = (function () { var tree = createTree(), id = 0; return function (age) { tree.insert(id, { age: age }); this.id = id++; this.grow = grow; this.destroy = destroy; }; function grow() { tree.get(this.id).age++; } function destroy() { tree.remove(this.id); } }()); 

我们使用function红黑树来有效地插入,删除和获取O(log n)时间的对象的私有属性。 因此,举例来说,您一次创build了Person 2251799813685248个实例。 它仍然只需要51个操作来从树中插入,移除和获取对象。

你可以使用它如下:

 var dan = new Person(10); dan.grow(); dan.age; // undefined dan.destroy(); // frees shared memory 

不过,我不会推荐这种方法,因为:

  1. 它不必要地使事情复杂化。
  2. 如果你忘记打电话destroy那么你将浪费大量的记忆。
  3. 每个“特权”function都有额外的开销。
  4. secret对象所做的更改不会反映在私有variables上。

相反,我会build议你只是使用公共财产的一切。 根本没有理由使用私人财产。 你害怕什么?


编辑:如果你想要的是防止你的私人属性通过console.log打印出来,那么你可以使他们不可枚举:

 function Person(age) { Object.defineProperty(this, "age", { enumerable: false, writable: true, value: age }); } Person.prototype.grow = function () { this.age++; }; 

现在age属性(虽然公开)不会出现for in循环或通过console.log 。 总之你得到了两全其美。

正如我在评论中所说的那样,绝对不需要使用共享特权方法。 简单地让所有的variables公开和不可枚举。

另外在它们前面加一个下划线来表示它们不应该被篡改。 所有优秀的JavaScript程序员都使用这个约定。

那么,正如你所说,特权方法是通过将它们放在构造函数的作用域中来创build的。 按照这个定义,它们不能在实例之间共享 ; 否则他们将无法访问特定于实例的范围。