在Javascript中,当访问非静态私有变量时,如何使对象的函数只驻留在内存中一次
考虑以下java代码在Javascript中,当访问非静态私有变量时,如何使对象的函数只驻留在内存中一次,javascript,function,design-patterns,constructor,private-members,Javascript,Function,Design Patterns,Constructor,Private Members,考虑以下java代码 class x { private boolean a; public void DoSomethingUsingA() { ....... // "a" referenced here } } x X = new x(); x Y = new x(); X和Y都有DoSomethingUsingA(),但该函数在内存中只创建一次 现在,如果您在javascript中尝试这一点 function x() { var a;
class x {
private boolean a;
public void DoSomethingUsingA() {
....... // "a" referenced here
}
}
x X = new x();
x Y = new x();
X和Y都有DoSomethingUsingA(),但该函数在内存中只创建一次
现在,如果您在javascript中尝试这一点
function x() {
var a;
this.DoSomethingUsingA= function() {
........ // "a" referenced here
}
}
var X = new x();
var Y = new y();
这里的DoSomethingUsingA()在内存中为每个对象X和Y定义了两次
另一种尝试是
var x = (function() {
var a;
function constructor() {
........
}
constructor.prototype.DoSomethingUsingA = function() {
....... // "a" referenced here
}
return constructor;
}())
var X = new x();
var Y = new y();
现在DoSomethingUsingA()在内存中只定义一次,但是私有变量在所有派生对象中都是静态的
问题:
如何让所有派生对象的函数在内存中只定义一次,同时访问每个对象的非静态私有变量。一种方法可以使值可引用,而无需在实例上直接暴露给每个值
function Foo(b) {
var env = {}; // Object to hold variables
this._getEnvironment = function () { // might want to make this non-enumerable
return env;
};
env.bar = b; // example
}
Foo.prototype.getBar = function () { // inherited, shared
var env = this._getEnvironment();
return env['bar'];
};
var x = new Foo(1),
y = new Foo(2);
x.getBar(); // 1
y.getBar(); // 2
// but remember
x._getEnvironment()['bar']; // 1, still reachable
现在是的,每个实例都有一个不同的\u getEnvironment
函数,但所有其他函数现在都是共享的
我使用了一个Objectenv
,因为这是一种安全的查找值的方法,而属性查找是使用哈希表完成的,速度非常快
JavaScript从来都不是真正安全的,所以虽然您可以使用闭包使其更难访问,但不要相信有人会绕过您尝试实现的任何安全措施
如何让所有派生对象的函数在内存中只定义一次,同时访问每个对象的非静态私有变量
你不能。“私有”变量,即专用于实例的作用域中的局部变量,只能通过闭包访问,即需要在同一作用域中创建的特权函数
请注意,它没有什么问题,函数比您想象的要便宜。考虑不要试图隐藏您的私有变量太多 尽管在Python或JavaScript等语言中,您可以使用一些巧妙的技巧使某些属性对类用户不可见,但在这些语言中,没有自然的方法或合适的工具来实现这一点。因此,如果您尝试进行这种构造,您将以诸如“静态”env对象或同一函数的多个副本之类的麻烦解决方案结束 引用到类似问题,完全适用于JavaScript: 这是文化。在Python中,您不会写入其他类的实例或类变量。在Java中,如果您真的想这样做,没有什么可以阻止您这样做——毕竟,您可以随时编辑类本身的源代码以达到相同的效果。Python放弃了安全性的伪装,鼓励程序员负责任。实际上,这非常有效 如果您决定不强制执行此类隐私,则有两种工具和约定可以使您的“私有”VAR易于使用:
function X() {
// constructor
}
Object.defineProperty(X.prototype, "__a", {
"writable": true,
"value": null
// "configurable" and "enumerable" are false by default
});
X.prototype.doSomethingUsingA = function() {
this.__a = "somevalue";
// ...
}
JavaScript没有一个“私有的”和“公共的”,为了访问这样的东西,你需要使它的引用环境可能是一个坏的名字选择,你可能想考虑调用它,例如GestStaseCavaRabeLeEMS,我在这个问题中有一些歧义(以GET…()为例)。我现在已经修好了。它不是关于引用和返回私有变量,而是关于在函数中使用它们。此外,“getEnvironmentVariable”将在中创建两次memory@man我说过每个实例将获得一个新的
gEnv
,区别在于所有其他函数都可以通过gEnv
,因此不需要有新实例themselves@man您试图解决的问题假设存在“私有”和“公共”两种情况,在JavaScript中,这些概念根本不存在。您可以使用作用域和闭包来创建类似的内容,但它与具有该功能的语言不同。也许你应该考虑一下为什么你想要一些私人的东西,如果不是这样,那真的重要吗?“编辑”是Crockford对该主题的理解。请将其设置为公共属性,可能带有下划线前缀。您的getEnvironmentVariable
不安全,假装安全。此外,你还需要一些类似于getter的东西——将一切都复杂化。