Каковы эти паттерны в этом примере 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);
У меня есть два вопроса:
-
Почему
var app = app || {}
в каждом файле? -
В чем разница между ними?
$(function(){})
,(function(){})()
, и(function($))(jQuery)
?
2 ответа:
app
переменная является глобальной и инкапсулирует все основное приложение, чтобы минимизировать загрязнение глобального пространства имен. здесь вы можете найти более подробную информацию о шаблонах пространства имен.
var app = app || {}
инициализирует глобальную переменнуюapp
новым пустым объектом, если он еще не инициализирован. Иначе он останется нетронутым.Функции:
$(function(){})
- это сокращение для jQuery$(document).ready(function(){})
. Docs(function(){})()
является выражение немедленно вызываемой функции (IIFE) без параметров(function($){ /* here $ is safe jQuery object */ })(jQuery)
is IIFE с параметром -jQuery
объект будет передан как$
в эту анонимную функцию
$(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 **/ } })();