Доступ к "общедоступным" методам из методов "Private" в классе javascript
Есть ли способ вызвать "общедоступные" функции javascript из "private" в классе?
Ознакомьтесь со следующим классом:
function Class()
{
this.publicMethod = function()
{
alert("hello");
}
privateMethod = function()
{
publicMethod();
}
this.test = function()
{
privateMethod();
}
}
Вот код, который я запускаю:
var class = new Class();
class.test();
Firebug дает эту ошибку:
publicMethod не определен: [Break this this error] publicMethod();
Есть ли другой способ вызвать publicMethod() в privateMethod() без доступа к глобальной переменной класса [т.е. class.publicMethod()]?
Ответы
Ответ 1
Принятый ответ имеет, возможно, нежелательный побочный эффект, что отдельные экземпляры publicMethod
, test
и privateMethod
будут созданы в каждом экземпляре. Идиома для избежания этого:
function Class()
{}
Class.prototype=(function()
{
var privateMethod = function(self)
{
self.publicMethod();
}
return
{
publicMethod: function()
{
alert("hello");
},
test: function()
{
privateMethod(this);
}
};
}());
Другими словами, вам нужно передать this
в частную функцию в качестве аргумента. В свою очередь, вы получаете прототип true, не загрязняя каждый экземпляр своими собственными версиями частных и общедоступных функций.
Ответ 2
Вы можете сохранить переменную в области конструктора, чтобы сохранить ссылку на this
.
Обратите внимание: В вашем примере вы не указали var
до privateMethod = function()
, сделав это privateMethod
глобальным. Я обновил решение здесь:
function Class()
{
// store this for later.
var self = this;
this.publicMethod = function()
{
alert("hello");
}
var privateMethod = function()
{
// call the method on the version we saved in the constructor
self.publicMethod();
}
this.test = function()
{
privateMethod();
}
}
Ответ 3
Ответ torazaburo является лучшим, поскольку он позволяет избежать создания нескольких копий частных членов. Я удивлен, что Крокфорд вообще этого не упоминает. В качестве альтернативы, в зависимости от синтаксиса, который вы предпочитаете для объявления публичных функций-членов, вы можете сделать это:
function Class()
{}
(function() {
var privateMethod = function(self) {
self.publicMethod();
};
Class.prototype.publicMethod = function() {
alert('hello');
};
Class.prototype.test = function() {
privateMethod(this);
};
}());
Ответ 4
Этот подход не является целесообразным? Я не уверен, хотя
var klass = function(){
var privateMethod = function(){
this.publicMethod1();
}.bind(this);
this.publicMethod1 = function(){
console.log("public method called through private method");
}
this.publicMethod2 = function(){
privateMethod();
}
}
var klassObj = new klass();
klassObj.publicMethod2();