Это ключевое слово в шаблоне модуля?

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

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

MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var bla = {};

    bla.somefunction = function() {
        //do stuff
    };

    //add more stuff to bla
    return bla;
}());

То, что они имеют по всему своему коду:

MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var that = this;

    that.somefunction = function() {
        //do stuff
    };

    //add more stuff to that
    return that;
}());

Теперь, конечно, потому что функция не вызывается как конструктор с new ключевое слово или как метод, this связан с window и они определяют that как this, Таким образом, они в основном сбрасывают все в глобальном объекте, и все их имена подмодулей на самом деле являются псевдонимами для window, Есть ли какая-то причина, по которой кто-то хотел бы сделать это? Или это действительно так неправильно, как мне кажется?

Редактировать:

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

Изменить 2:

Также я посмотрел на скрипты, исполняемые в Firebug, и они определенно добавляют все в windowэтот объект - полный беспорядок.

2 ответа

Решение

Да, это выглядит неправильно.

MODULENAME = MODULENAME || {}; // missing var

var MODULENAME.SUBMODULENAME = (function() { // probably the missing var from above...
    var that = this;
    //add some stuff to that
    return that; // that is the WINDOW- wrong.
}());

ДЕМО за ущерб, который он может нанести:

var x = function() {
    alert('out');
}
var MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var that = this;
    that.x = function() {
        alert('DAMAGE');
    }
}());

x();​ // alert DAMAGE and not "out" - messed up with the global object!

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

function somefuncion() {
  ...
}

Если их целью является добавление свойств (в данном случае методов) к объекту, что более вероятно, тогда:

MODULENAME.SUBMODULENAME.somemethod = function() { /* do stuff */ };

Если есть необходимость условно создавать методы, например, на основе обнаружения признаков, то может подойти следующее:

(function(global, undefined) {

  // In here global is the global object
  global.MODULENAME = global.MODULENAME || {};
  global.MODULENAME.SUBMODULENAME = global.MODULENAME.SUBMODULENAME || {};

  // and undefined is undefined, belt and braces approach
  undefined = void 0;

  // Direct assignment
  function somemethod() {
      //do stuff      
  };

  // Assign directly to the "namespace" object
  MODULENAME.SUBMODULENAME.somemethod = somemethod;

  // Conditional assignment
  if ( sometest ) {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};

  // Try another way...
  } else if (someOtherTest) {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};

  // Default
  } else {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};
  }

  // Clean up 
  global = null;

}(this)); 

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

Другие вопросы по тегам