如何创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
不过,我不会推荐这种方法,因为:
- 它不必要地使事情复杂化。
- 如果你忘记打电话
destroy
那么你将浪费大量的记忆。 - 每个“特权”function都有额外的开销。
- 对
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的。 按照这个定义,它们不能在实例之间共享 ; 否则他们将无法访问特定于实例的范围。