Jef*_*y04 7 javascript prototype
在阅读了Javascript的原型继承模型后,我改变了构建类的风格
var Some_Class = function() {
this.public_method = function() {
};
(function() {
// constructor
}).call(this)
}
Run Code Online (Sandbox Code Playgroud)
至
var Some_Class = function() {
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
};
Run Code Online (Sandbox Code Playgroud)
虽然我知道这是一个很好的做法,但我不允许从公共方法访问私有方法
var Some_Class = function() {
var private_member = 'whatever';
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
return private_member; // not possible
};
Run Code Online (Sandbox Code Playgroud)
在阅读了这里的文章(Closure-created constructor)后,我就出来了
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)
}
Run Code Online (Sandbox Code Playgroud)
但是,这样做的缺点是什么?!或者,如果我想在公共方法中访问私有成员,是否有更好的方法?
Joh*_*ica 11
我的回答是没有答案:privateJavaScript中没有内置访问权限,但是没关系,因为YAGNI.以下是我private在代码中创建成员的方法:
function Some_Class() {
this._private_member = 'whatever';
}
Some_Class.prototype._private_method = function() {
};
Run Code Online (Sandbox Code Playgroud)
那太好了.当唯一真正的目的private是保护自己免受......自己时,跳过篮球并不值得.
(我说这花了很多时间自己玩弄关闭和原型设计的每一个排列,就像你一样,最后说"拧它,它不值得".)
Fai*_*ali 10
使用函数范围变量和闭包来模拟私有变量/函数是javascript社区中一个成熟的习惯用法.如果该变量确实是私有的,我认为这种方法没有任何缺点(尽管有些人声称某些浏览器/主机上的高性能代码必须注意创建多少个闭包).
在您的示例中,private_method(及其环境)在所有对象之间共享 - 因为您的public_method闭包仅在第一次构造对象时创建(并绑定到构造函数的prototype属性,用于设置创建的对象的内部原型链) - 所以使用的private_method只是第一次创建的那个.
以下是一些示例代码,可帮助说明发生的情况:
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
你确定这是你想要的吗?
如果你的private_method不需要引用封闭对象的状态,那么我认为按照你的方式做事情几乎没什么好处.
我通常做的事情(如果我必须使用'new'来创建我的对象)如下:
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'构造对象时,都会重新创建所有闭包.但除非我的剖析器告诉我这个设计选择需要优化,否则我更喜欢它的简洁性和清晰度.
此外,我也没有看到您的代码执行以下操作的好处:
(function() { }).call(this); // call the constructor
为什么要在构造函数中创建单独的作用域?