在Javascript中访问私有成员的更好方法 [英] Better way to access private members in Javascript
问题描述
在阅读了Javascript的原型继承模型之后,我改变了构建类的风格来自
After reading a bit on Javascript's prototypical inheritance model, I change my style of constructing a class from
var Some_Class = function() {
this.public_method = function() {
};
(function() {
// constructor
}).call(this)
}
到
var Some_Class = function() {
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
};
虽然我知道这是一个很好的做法,但我不允许从访问私有方法公共方法
Although I understand that this is a good practice, but I am not allowed to access private methods from the public method anymore
var Some_Class = function() {
var private_member = 'whatever';
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
return private_member; // not possible
};
阅读完文章这里(Closure-created constructor),然后我出来了
After reading through an article here (Closure-created constructor), then I came out with this
var Some_Class = function() {
var private_member = 'whatever',
private_method = function(_some_value) {
// private method implementation
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
然而,这样做有什么缺点?!或者,如果我想在公共场所访问私人会员,是否有更好的方法方法?
However, what are the drawbacks of doing this?! or is there a better way of doing this if I want to access private member in the public method?
推荐答案
使用函数范围变量和闭包来模拟私有变量/函数是javascript社区中一个成熟的习惯用法。如果该变量确实是私有的,我认为这种方法没有任何缺点(尽管有些人声称某些浏览器/主机上的高性能代码必须注意创建多少个闭包)。
The use of function scope variables and closures to simulate private variables/functions is a well established idiom in the javascript community. If the variable is truly intended to be private, I see no drawback to this approach (although some claim that performant code on certain browsers/hosts has to pay attention to how many closures get created).
在您的示例中,private_method(及其环境)在所有对象之间共享 - 因为您的public_method闭包仅在第一次构造对象时创建(并且绑定到构造函数的prototype属性,用于设置创建的对象的内部原型链) - 因此使用的private_method只是第一次创建的那个。
In your example, the private_method (and its environment) is shared across all objects - since your public_method closure is created only the first time the object is constructed (and bound to the constructor's prototype property that sets the created object's internal prototype chain) - so the private_method that is used is only the one that was created the first time.
以下是一些示例代码,可帮助说明发生的情况:
Here is some sample code that will help illustrate what is going on:
var global = 1;
var Some_Class = function() {
var private_method = 'whatever';
var now = ++global;
print("outer now: " + now );
private_method = function(_some_value) {
// private method implementation
print("inner now: " + now);
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
new Some_Class().public_method(); // outer now: 2, inner now: 2
new Some_Class().public_method(); // outer now: 3, inner now: 2
new Some_Class().public_method(); // outer now: 4, inner now: 2
你确定这是你想要的吗?
Are you sure that is what you want?
如果你的private_method不需要引用封闭对象的状态,那么我认为按照你的方式做事情几乎没什么好处。
If your private_method does not need to refer to the enclosing object's state, then I see little benefit in doing things the way you are doing.
我通常做的事情(如果我必须使用'new'来创建我的对象)如下:
What I usually do (if i have to use 'new' to create my object) is the following:
function MyClass() {
var private_var = 1;
function private_func()
{
}
this.public_func = function()
{
// do something
private_func();
}
this.public_var = 10;
}
var myObj = new MyClass();
这种方法的缺点是每次通过'new'构造对象时,都会重新创建所有闭包。但除非我的探查器告诉我这个设计选择需要优化,我更喜欢它的简洁性和清晰度。
The downside to this approach is that each time you construct the object via 'new' you re-create all the closures. But unless my profiler tells me that this design choice needs to be optimized, i prefer its simplicity and clarity.
此外,我看不到你的代码中的好处以下之一:
Also I don't see the benefit in your code of doing the following either:
(function() { }).call(this); // call the constructor
为什么要在构造函数中创建单独的作用域?
Why are you creating a separate scope in your constructor?
这篇关于在Javascript中访问私有成员的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!