2012-06-14 3 views
0

У меня есть класс, который имеет приватную переменную с функцией общественного сеттер/добытчика:Доступ к локальной переменной с помощью прототипа

function Circle(rad) { 
    var r = rad; 

    this.radius = function(rad) { 
     if(!arguments.length) return r; 
     r = rad; 
     return this; 
    } 
} 

var shape = new Circle(10); 
console.log(shape.radius()); // 10 
shape.r = 50; 
console.log(shape.radius()); // 10 

Как я могу повторить это с помощью Object.prototype? Или, когда я хочу использовать закрытие вместо Object.prototype? Это самое близкое, что я мог придумать, но, как вы можете видеть, вы можете напрямую изменить свойство.

function Circle(r) { 
    this.r = r; 
} 

Circle.prototype.radius = function(r) { 
    if(!arguments.length) return this.r; 
    this.r = r; 
    return this; 
}; 

var shape = new Circle(10); 
console.log(shape.radius()); // 10 
shape.r = 50; 
console.log(shape.radius()); // 50 
+2

Вы или не хотите, чтобы можно было установить его снаружи? –

+0

Я хочу, чтобы он был доступен через публичные функции getter/setter, которые я определяю. Я не хочу, чтобы кто-либо из класса имел открытый доступ к переменной напрямую. – Wex

+0

«Как я могу реплицировать это, используя объект-прототип класса?» Я не совсем понимаю этот вопрос. Почему вы хотите воспроизвести определенное поведение с помощью языковой функции, которая не может быть реализована? – millimoose

ответ

4

Если вы собираетесь использовать прототип, чтобы сохранить свойство объекта, они доступны из любого кода, который имеет ссылку на объект. Невозможно делать то, что вы хотите.

что многие JS дэвы сделать, это просто назвать личные свойства с ведущим подчеркиванием так, что другие не знают, возиться с ним, но это не дает вам никакой реальную защиту вне всяких предложения

Причин закрывающие использование подхода, основанного

  • Истинные частные переменные, быть уверенным, что ни один испортит с рядовыми

Причины использовать прототип

  • Меньше памяти не используется (нет закрытия для каждого экземпляра)
  • легче отлаживать (свойства видны на самом объекте)
  • Позволяет обезьяна латание

Читатели: Пожалуйста, отредактируйте ответ с причинами того, что вы считаете лучшим решением.

+0

Есть ли недостаток, чтобы просто придерживаться моей первой версии кода? Или есть альтернатива, которая, возможно, была бы лучше? – Wex

+1

Недостатком является то, что для каждого объекта создается новое закрытие, дополнительная память. Я не параноик о частных свойствах, я использую символы подчеркивания для обозначения частных. Если кто-то прикасается к нему за пределами класса, я набрасываю их на голову, пока они не научатся! –

+0

Значит, лучше использовать Object.prototype для создания закрытий? – Wex

0

Я нахожу ваш первый круг очень странным. Если вы перепишите его вот так:

 function Circle(rad) { 
      var r = rad; 

      this.radius = function(rad) { 
       if(rad){r = rad;} 
       return r; 
      } 
     } 

Я думаю, теперь он делает то, что вы имеете в виду. r является частным, а радиус действует как функция getter/setter. Полагая г, как это:

shape.r = 50; 

не имеет смысла, потому что ваш первый круг не имеет свойство г, он имеет только локально контекстный переменный г. Это должно вызвать некоторую ошибку.

Я не вижу способа использования прототипа в вашей второй версии Circle, потому что функция в цепочке прототипов не будет иметь доступа к переменной, созданной в объекте Circle. И вообще, в вашей второй версии r является свойством Circle, а не частной переменной в теле функции.

+1

Что делать, если вы установили радиус в 0? Ваше изменение кода будет игнорировать его. Нет ничего плохого в подходе к OP, и ваше предложение не имеет ничего общего с реальной проблемой. –

+0

Из-за динамической природы Javascript установка 'shape.r = 50' создаст публичное свойство' r' со значением '50'. – Wex

+0

Чтобы объяснить, что упоминает Уэкс, JS позволяет создавать свойства для любых объектов. 'shape.r = 50' просто устанавливает свойство объекта (и это свойство никогда не будет считаться) –

Смежные вопросы