Каковы эти паттерны в этом примере Backbone TodoMVC


Глядя вTodoMVC магистральные коды пример . Структура в js / fold:

├── app.js
├── collections
│   └── todos.js
├── models
│   └── todo.js
├── routers
│   └── router.js
└── views
    ├── app-view.js
    └── todo-view.js

Приложение.js

var app = app || {};
$(function () {
    'use strict';
    // kick things off by creating the `App`
    new app.AppView();
});

Коллекции / todos.js

var app = app || {};

(function () {
    'use strict';
    var Todos = Backbone.Collection.extend({
    model: app.Todo,
    app.todos = new Todos();
})();

Модели / todo.js

var app = app || {};

(function () {
    'use strict';
    app.Todo = Backbone.Model.extend({
    });
})();

Просмотры / app-view.js

var app = app || {};
(function ($) {
    'use strict';
    app.AppView = Backbone.View.extend({
})(jQuery);

У меня есть два вопроса:

  1. Почему var app = app || {} в каждом файле?

  2. В чем разница между ними?$(function(){}), (function(){})(), и (function($))(jQuery)?

2 3

2 ответа:

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

    var app = app || {} инициализирует глобальную переменную app новым пустым объектом, если он еще не инициализирован. Иначе он останется нетронутым.

  2. Функции:

$(function() {
  console.log("Document ready event");
});

$(document).ready(function() {
  console.log("Document ready event");
});

(function() {
  console.log("Immediately-invoked function expression without parameters");
})();

(function($) {
  console.log("Immediately-invoked function expression with parameter. $ is a jQuery object here:");
  console.log($.fn.jquery);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

В то время как Юрий объяснил разницу между всеми паттернами, в нем отсутствует "зачем" вам это нужно.

Пространство имен и область действия

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

См. как объявить a пространство имен .

Глобальное пространство имен

var app = app || {}; // if it doesn't exist yet, make it an new object.

Чтобы избежать загрязнения глобального пространства имен (то есть превращения всего в глобальную переменную), вы создаете только одну переменную, в которую вставляете все остальные модули вашего приложения.

Затем каждый файл экспортирует свой модуль в эту единственную глобальную переменную.

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

Если мы посмотрим на TodoMVC пример , они включили файлы в определенном порядке:

<script src="js/models/todo.js"></script>
<script src="js/collections/todos.js"></script>
<script src="js/views/todo-view.js"></script>
<script src="js/views/app-view.js"></script>
<script src="js/routers/router.js"></script>
<script src="js/app.js"></script>

Область применения

Представьте, что вы объявили var test = 2; в файле, и это критическая переменная, которая используется во всем этом модуле. Затем, в другом файле, вы копируете хороший шаблон, который вы использовали внутри первого модуля. Вы только что переопределили переменную test, и теперь она инволюционно разделяется между двумя модулями.

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

var app = app || {}; // global

(function () {
    // private to this scope
    var Todos = Backbone.Collection.extend({});

    // export the Todos constructor to the global app namespace
    app.Todos = Todos;

    function localFunction(param) { /** snip **/ }
})();