Является ли обычным JS писать геттеры для простых свойств? - PullRequest
2 голосов
/ 09 октября 2011

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

self.isAlive = function() {
  return self.alive;
}

Ответы [ 5 ]

2 голосов
/ 09 октября 2011

Кажется, вы говорите о свойствах в классическом смысле ООП, то есть о свойствах классов.В текущей версии Javascript симуляция этого поведения не совсем чистая.Рассмотрим следующий пример:

    var Widget = function() {
        var private = 'private';
    }

«Виджет» - это функция конструктора, а экземпляр «private» будет создан в области действия только функции конструктора.Это означает, что есть только один способ получить доступ к 'private' из области действия функции конструктора:

    var Widget = function() {
        var private = 'private';
        this.getPrivate = function() {
            return private;
        }
    }

Это позволит скрыть приватную переменную для каждого экземпляра Widget, но, к сожалению, теперь getPrivateбыть добавлен к каждому экземпляру виджета.Вы можете увидеть это в функции конструктора с помощью оператора this.getPrivate = ....Каждый раз, когда вы создаете экземпляр Widget с использованием var widget1 = new Widget(), к этому конкретному экземпляру добавляется новая функция 'getPrivate'.

Обычный способ создания повторно используемых компонентов в Javascript - это использование его реализации.прототипического наследования.Вы назначаете объект-прототип функции конструктора, который будет иметь общие методы и свойства во всех экземплярах компонента.Ниже я приведу пример для объяснения, но есть некоторые недостатки прототипного наследования, о которых вам следует знать, если вы работаете с объектно-ориентированным JavaScript.Отличный ресурс .

Вот пример того, как это может сыграть в вашем примере:

    var Widget = function() {
        this.alive = true;
    }
    Widget.prototype.isAlive = function() {
        return this.alive;
    }
    var widget1 = new Widget();
    widget1.isAlive();  // returns true

Проблема здесь в том, что свойство aliveдобавляется к объекту, и, таким образом, он общедоступен, т. е. любой пользователь вашего виджета может просто просмотреть DOM в своем любимом варианте FireBug и увидеть (а также свободно изменить) это свойство.

Рассмотрим вариант, в котором вы пытаетесь скрыть alive для внешних пользователей.Поскольку alive является свойством Widget экземпляров, вам нужно включить код, чтобы скрыть его в конструкторе, как показано ниже:

    var Widget = function() {
        var alive = true;
    }

Однако, как указано в начале этого поста, alive в этом случае доступна только для области действия функции конструктора;следовательно, он не будет доступен для методов по прототипу.Причина этого заключается в том, что каждый из этих методов не имеет ту же область видимости, что и функция конструктора, поскольку Javascript имеет только область видимости функции.

В заключение, если вы пытаетесь скрыть данные в повторно используемом компоненте,Javascript не предоставляет чистый способ сделать это.Если вы не возражаете против того, чтобы в каждом экземпляре компонента выделялась новая память для одних и тех же методов, вы можете использовать мой второй пример кода в этом посте.Однако, если вы предпочитаете, чтобы ваши методы выделялись в памяти только один раз, вам нужно будет предоставить свойства для экземпляра объекта, например, this.alive = true.

2 голосов
/ 09 октября 2011

Все зависит от реализации.

Если вы чувствуете, что свойство всегда будет иметь значение, доступ к свойству будет адекватным.Если вам кажется, что будет какая-то логика, определяющая возвращение «правильно отформатированного» значения, я бы использовал метод (или, если значение может быть динамическим, основанным на других факторах, метод - хорошая идея).

Чтобы пойти дальше, другие языки, такие как C #, имеют свойства, позволяющие безопасно выставлять значения, но не обязательно изменять их.У JS нет такого метода его защиты, поэтому часто get<Var> используется для раскрытия свойства, но только для чтения.

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

1 голос
/ 09 октября 2011

Вы можете использовать:

function isAlive(){
    return arguments.callee.alive;
}
isAlive.alive=true;

Похоже, что все в порядке в строгом режиме.

Еще один способ сделать это -

function isAlive(){
    return isAlive.alive;
}
isAlive.alive=true;

Но проблема в том, что кто-то может использовать имя в виде строки или переименовать функцию и т. Д. ... и вы можете потерять статус.

1 голос
/ 09 октября 2011

Это хорошая практика, если вы не хотите, чтобы внешний код js изменял вашу собственность. Если это желаемый эффект, вы можете рассмотреть назначение этого свойства с помощью var, а не делать его свойством этого объекта. Таким образом, ваш код внутри объекта может изменить его, но к нему можно получить доступ только через ваш геттер

var alive = false;
function isAlive(){ return alive;}
1 голос
/ 09 октября 2011

Это субъективно. Использование геттеров и сеттеров очень обсуждается. Некоторые люди (например, я) говорят, что вы всегда должны использовать методы получения и установки, чтобы следовать принципу инкапсуляции, в то время как другие говорят, что вы не должны этого делать, поскольку ваше приложение станет не поддерживаемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...