Использование переменных области видимости функций и замыканий для имитации частных переменных / функций является хорошо известной идиомой в сообществе 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
Почему вы создаете отдельную область в конструкторе?