调查todomvc backbone codes example。 js / fold中的结构:
├── app.js
├── collections
│ └── todos.js
├── models
│ └── todo.js
├── routers
│ └── router.js
└── views
├── app-view.js
└── todo-view.js
app.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({
});
})();
浏览量/应用-view.js
var app = app || {};
(function ($) {
'use strict';
app.AppView = Backbone.View.extend({
})(jQuery);
我有两个问题:
为什么每个文件中都有var app = app || {}
?
$(function(){})
,(function(){})()
和(function($))(jQuery)
之间有什么区别?
答案 0 :(得分:4)
app
变量是全局变量,并封装整个Backbone应用程序,以最大限度地减少全局命名空间污染。 Here您可以找到有关命名空间模式的更多详细信息。
var app = app || {}
使用新的空对象初始化全局app
变量(如果尚未初始化)。否则它将不受影响。
功能:
$(function(){})
是jQuery' $(document).ready(function(){})
的快捷方式。 Docs (function(){})()
是Immediately-invoked function expression (IIFE),不含参数(function($){ /* here $ is safe jQuery object */ })(jQuery)
是带参数的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>
&#13;
答案 1 :(得分:4)
虽然Yurii解释了所有模式之间的差异,但它缺少您需要这些模式的“原因”。
以下模式的总体目标主要是命名空间和范围,具有不同的好处。避免污染全局命名空间是一种很好的做法,并且由于JavaScript没有将命名空间作为核心功能,因此其他模式已经淹没以解决这个问题。
请参阅How do I declare a namespace。
var app = app || {}; // if it doesn't exist yet, make it an new object.
为了避免污染全局命名空间(AKA使一切变为全局变量),您只创建一个变量,在其中插入您的每个其他模块应用
然后,每个文件将其模块导出到唯一的全局变量中。
请注意,如果模块依赖于另一个模块,文件的顺序仍然很重要。
如果我们查看TodoMVC example,则会按特定顺序包含文件:
<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
变量,现在,它是两个模块之间的共享。
为了使本地函数和变量对模块是私有的,您可以使用Immediately-invoked function expression (IIFE)来限定它们。 Block scoping相对较新且尚未得到很好的支持,因此最安全的方法是使用函数范围。
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 **/ }
})();