В javascript, псевдоним пространства имен?

В javascript я не должен иметь псевдоним пространства имен?

В главе "Именование" Руководство по стилю JavaScript JavaScript:

//Do not alias namespaces.
myapp.main = function() {
  var namespace = some.long.namespace;
  namespace.MyClass.staticHelper(new namespace.MyClass());
};

Но я не могу полностью понять эту проблему. Почему нет краткого описания пространства имен?

Ответ 1

Вы меняете this, что может сломать функции в псевдонимом пространстве имен. Пример:

var foo = {
    bar: function () {
        console.log(this.baz);
    },
    baz: 42
};

foo.bar(); // prints 42
var alias = foo.bar;
alias(); // prints undefined, because `this` is no longer `foo`

Ответ 2

В документе явно указано, что вы должны использовать псевдонимы с именами, локальными именами:

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

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

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

my.long.namespaces.myFunc()
// this refers to the same function, but is a different reference
var myLocalNamespace = my.long.namespace;
namespace.myFunc();
// and you can easily introduce bugs which are hard to find
myLocalNamespace.myFunc = "foobar";
myLocalNamespace.myFunc()  // throws a type error because myFunc is now a string

Эта ошибка трудно найти.

У Aliasing есть много преимуществ, хотя. Каждый элемент поиска в JavaScript стоит времени. Таким образом, наличие кода, который постоянно нужно искать в цепочке членов, направляется впустую. Так как стоимость локального var незначительна, настоятельно рекомендуется использовать локальные вары всякий раз, когда вы ссылаетесь на длинные пространства имен, результаты функции (например, $("something")) и т.д. Кроме того, он делает ваш код более читабельным. Рассмотрим следующее:

var handleNamespace = function() {
    my.really.long.namespace.foo = "bar";
    my.really.long.namespace.doIt(my.really.long.namespace.foo);
    my.really.long.namespace.member = my.really.long.namespace.somethingElse(my.really.long.namespace.addOne(2));
};

Как вы видите, это довольно запутывает. Избавление от повторяющегося кода экономит вычислительную мощность и делает ваш код более удобочитаемым.

var handleNamespace = function() {
    var namespace = my.really.long.namespace,
        three = namespace.addOne(2);

    namespace.foo = "bar";
    namespace.doIt(namespace.foo);
    namespace.member = namespace.somethingElse(three);
};

Ответ 3

Я думаю, что это правило применяется только к объектам пространства имен:

Имя локального псевдонима должно совпадать с последней частью типа.

То, что вы должны использовать псевдоним (см. правило выше), - это то, что вы действительно хотите использовать, здесь MyClass конструктор/пространство имен.

Улучшенный код:

myapp.main = function() {
  var myClass = some.long.namespace.MyClass;
  myClass.staticHelper(new myClass());
};

Конечно, это не относится к пространствам имен, некоторые свойства которых вы хотите использовать. Если ваш код также нуждался в namespace.TheirClass, это было бы нормально.