Следует ли объявлять функции с минимальной областью видимости?

По моему опыту, большинство функций JS, функций конструктора или функций шаблона модуля объявляются как глобальные или привязаны к объекту глобального пространства имен. В любом случае эти идентификаторы доступны глобально.

Из любой строки кода в вашей системе вы можете получить:

mod1 = somepackage.SomeModule(); // couple to me!

Вот краткий пример JS, но эта идея применима и к другим языкам.

function A () { // couple to me!
  return { foo: "bar" };
};

(function () {
  function B () { // don't couple to me!
    function c () { // really don't couple to me!
      return "buzz";
    };
    return { fizz: c() }; // 0 scope lookup
  };
  var a = A(); // 1 scope lookup
  var b = B(); // 0 scope lookup
})();

var a1 = A(); // 0 scope lookup
var b1 = B(); // B is not defined

Поскольку глобальные переменные считаются вредными, насколько следует ограничивать видимость функций/классов? Каковы компромиссы?

Мой вопрос несколько мотивирован: 'когда допустимы глобальные переменные', 'альтернативы глобальным переменным' и 'возврат глобальных переменных'

Спасибо!


person Community    schedule 17.09.2010    source источник


Ответы (1)


Что ж, всегда лучше начинать с минимального масштаба, который вы можете увеличить, если есть требования. Но если вы сделаете что-то общедоступным с самого начала, будет очень сложно (почти невозможно) минимизировать объем, поскольку вам придется рефакторить/исправлять другой код в процессе.

Это одна из главных вещей при разработке API.

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

person Faisal Feroz    schedule 17.09.2010
comment
Я согласен, что сокращение масштаба — хорошее решение. Меня беспокоит то, что по сравнению с переменной, связанной с блоком или функцией, переменная, связанная с пакетом, доступна из гораздо большего количества строк кода. Это заставляет меня задаться вопросом, должны ли конструкторы определяться ближе всего к месту их первого использования. - person James; 17.09.2010
comment
Я думаю, что переменные должны быть закрытыми, если нет веских причин не делать этого (наследование и т. д.). - person Faisal Feroz; 17.09.2010
comment
Похоже, что уменьшение области также снижает возможность повторного использования, требуя изменения сигнатуры метода везде, где может быть передана фабрика. - person James; 17.09.2010
comment
Педантичным примером в Java и более близким к тому, о чем я говорю, будет класс, определенный и используемый только в методе. См.: stackoverflow.com/questions/2428186/ - person James; 17.09.2010