此 Backbone TodoMVC 示例中的这些模式是什么
What are these patterns in this Backbone TodoMVC example
调查 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();
});
collections/todos.js
var app = app || {};
(function () {
'use strict';
var Todos = Backbone.Collection.extend({
model: app.Todo,
app.todos = new Todos();
})();
models/todo.js
var app = app || {};
(function () {
'use strict';
app.Todo = Backbone.Model.extend({
});
})();
views/app-view.js
var app = app || {};
(function ($) {
'use strict';
app.AppView = Backbone.View.extend({
})(jQuery);
我有两个问题:
为什么每个文件中有 var app = app || {}
?
$(function(){})
、(function(){})()
、(function($))(jQuery)
有什么区别?
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>
虽然 解释了所有模式之间的区别,但缺少 "why" 您需要的这些。
命名空间和范围
以下模式的总体目标主要是命名空间和范围界定,具有不同的好处。避免污染全局命名空间是一种很好的做法,并且由于 JavaScript 没有将命名空间作为核心功能,因此出现了其他模式来解决这个问题。
见How do I declare a namespace。
全局命名空间
var app = app || {}; // if it doesn't exist yet, make it an new object.
为了避免污染全局命名空间(也就是使一切成为全局变量),您只创建一个变量,在您插入应用程序的所有其他模块。
然后,每个文件将其模块导出到唯一的全局变量中。
请注意,如果一个模块依赖于另一个模块,文件的顺序仍然很重要。
如果我们查看 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 来限定它们的范围。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 **/ }
})();
调查 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();
});
collections/todos.js
var app = app || {};
(function () {
'use strict';
var Todos = Backbone.Collection.extend({
model: app.Todo,
app.todos = new Todos();
})();
models/todo.js
var app = app || {};
(function () {
'use strict';
app.Todo = Backbone.Model.extend({
});
})();
views/app-view.js
var app = app || {};
(function ($) {
'use strict';
app.AppView = Backbone.View.extend({
})(jQuery);
我有两个问题:
为什么每个文件中有
var app = app || {}
?$(function(){})
、(function(){})()
、(function($))(jQuery)
有什么区别?
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>
虽然
命名空间和范围
以下模式的总体目标主要是命名空间和范围界定,具有不同的好处。避免污染全局命名空间是一种很好的做法,并且由于 JavaScript 没有将命名空间作为核心功能,因此出现了其他模式来解决这个问题。
见How do I declare a namespace。
全局命名空间
var app = app || {}; // if it doesn't exist yet, make it an new object.
为了避免污染全局命名空间(也就是使一切成为全局变量),您只创建一个变量,在您插入应用程序的所有其他模块。
然后,每个文件将其模块导出到唯一的全局变量中。
请注意,如果一个模块依赖于另一个模块,文件的顺序仍然很重要。
如果我们查看 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 来限定它们的范围。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 **/ }
})();