在 Javascript 原型中,有什么方法既可以利用信息隐藏又不会浪费内存?
Is there any way to make use of information hiding while not wasting memory in Javascript prototypes?
我正在关注 Crockford's guide to private methods in Javascript,但我遇到了一些困难。我正在尝试优化此代码
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
return dec() ? that.member : null;
};
}
通过在构造函数之外定义函数,这样每次创建新实例时都不会创建新的函数对象。
我仍然不知道如何为他称为私有方法的方法执行此操作(非常感谢任何帮助)。对于那些他称之为特权方法的人,这就是我正在尝试做的事情:
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
Container.prototype.service = function() {
return dec() ? that.member : null;
};
但如果我这样测试它
d1 = new Container("content");
d1.service();
我收到这个错误:
ReferenceError: dec is not defined
这是否意味着无法利用 Crockford 使用的 private/privileged 方法的优势,并通过将 class 的所有实例链接到同一个函数对象来优化内存使用?我希望你能证明我错了。
如果你不想在每次调用 Container
时创建一个新的 dec
,你可以将 Container
变成一个 IIFE - 定义 dec
当 Container
被定义,然后 return 来自 IIFE 的实际 Container
构造函数,因此 dec
只能从 Container
内部引用。要封装 secrets
,请使用由实例索引的 Map
而不是在构造函数中使用普通的 var secrets
,以便(共享)dec
和 service
函数可以查看和使用地图。
实际上,如评论所述,使用 WeakMap 可能更好,这样一旦实例被 GC 处理,实例的关联秘密就可以被垃圾回收:
const Container = (() => {
const secretsByInstance = new WeakMap();
function dec(instance) {
const secret = secretsByInstance.get(instance);
if (secret > 0) {
secretsByInstance.set(instance, secret - 1);
return true;
} else {
return false;
}
}
function Container(param) {
secretsByInstance.set(this, 3);
this.member = param;
}
Container.prototype.service = function() {
return dec(this) ? this.member : null;
};
return Container;
})();
d1 = new Container("content");
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());
我正在关注 Crockford's guide to private methods in Javascript,但我遇到了一些困难。我正在尝试优化此代码
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
return dec() ? that.member : null;
};
}
通过在构造函数之外定义函数,这样每次创建新实例时都不会创建新的函数对象。
我仍然不知道如何为他称为私有方法的方法执行此操作(非常感谢任何帮助)。对于那些他称之为特权方法的人,这就是我正在尝试做的事情:
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
Container.prototype.service = function() {
return dec() ? that.member : null;
};
但如果我这样测试它
d1 = new Container("content");
d1.service();
我收到这个错误:
ReferenceError: dec is not defined
这是否意味着无法利用 Crockford 使用的 private/privileged 方法的优势,并通过将 class 的所有实例链接到同一个函数对象来优化内存使用?我希望你能证明我错了。
如果你不想在每次调用 Container
时创建一个新的 dec
,你可以将 Container
变成一个 IIFE - 定义 dec
当 Container
被定义,然后 return 来自 IIFE 的实际 Container
构造函数,因此 dec
只能从 Container
内部引用。要封装 secrets
,请使用由实例索引的 Map
而不是在构造函数中使用普通的 var secrets
,以便(共享)dec
和 service
函数可以查看和使用地图。
实际上,如评论所述,使用 WeakMap 可能更好,这样一旦实例被 GC 处理,实例的关联秘密就可以被垃圾回收:
const Container = (() => {
const secretsByInstance = new WeakMap();
function dec(instance) {
const secret = secretsByInstance.get(instance);
if (secret > 0) {
secretsByInstance.set(instance, secret - 1);
return true;
} else {
return false;
}
}
function Container(param) {
secretsByInstance.set(this, 3);
this.member = param;
}
Container.prototype.service = function() {
return dec(this) ? this.member : null;
};
return Container;
})();
d1 = new Container("content");
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());