在这个Backbone TodoMVC示例中,这些模式是什么?

What are these patterns in this Backbone TodoMVC example

本文关键字:模式 是什么 Backbone TodoMVC      更新时间:2023-09-26

查看todomvc主干代码示例。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({
    });
})();

视图/app-view.js

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

我有两个问题:

  1. 为什么var app = app || {}在每个文件?

  2. $(function(){})(function(){})()(function($))(jQuery)有何区别

  1. app变量是全局的,封装了整个骨干应用程序以最小化全局命名空间污染。在这里您可以找到更多关于命名空间模式的详细信息。

    var app = app || {}用新的空对象初始化全局app变量,如果它还没有初始化。

  2. 功能:

    • $(function(){})是jQuery的$(document).ready(function(){})的快捷方式。文档
    • (function(){})()是一个不带参数的即时调用函数表达式(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>

虽然Yurii解释了所有模式之间的区别,但它缺少"为什么"您需要这些模式。

命名空间和作用域

以下模式的总体目标主要是名称空间和作用域,具有不同的优点。避免污染全局命名空间是一种很好的做法,而且由于JavaScript没有将命名空间作为核心特性,因此出现了其他模式来解决这个问题。

请参见如何声明命名空间。

全局名称空间

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 **/ }
})();