这是Backbone.js代码的示例(取自this教程):
// **This example illustrates the binding of DOM events to View methods.**
//
// _Working example: [2.html](../2.html)._
// _[Go to Example 3](3.html)_
//
(function($){
var ListView = Backbone.View.extend({
el: $('body'), // el attaches to existing element
// `events`: Where DOM events are bound to View methods. Backbone doesn't have a separate controller to handle such bindings; it all happens in a View.
events: {
'click button#add': 'addItem'
},
initialize: function(){
_.bindAll(this, 'render', 'addItem'); // every function that uses 'this' as the current object should be in here
this.counter = 0; // total number of items added thus far
this.render();
},
// `render()` now introduces a button to add a new list item.
render: function(){
$(this.el).append("<button id='add'>Add list item</button>");
$(this.el).append("<ul></ul>");
},
// `addItem()`: Custom function called via `click` event above.
addItem: function(){
this.counter++;
$('ul', this.el).append("<li>hello world"+this.counter+"</li>");
}
});
var listView = new ListView();
})(jQuery);
我不明白为什么必须先加(function($){...
。
任何人都可以向我解释这个吗?
答案 0 :(得分:7)
这是authoring jQuery plugins时的常见做法。
原因是您希望避免与可能在全局范围中使用$
符号的其他库发生冲突。通过将代码包装在一个带有一个参数(名为$
)的函数调用中并将jQuery
对象传递给该函数,可以确保避免冲突。
function($) { // declare an anonymous function that takes an argument $
// conflict safe code =)
}(jQuery); // pass the argument jQuery to the anonymous function
作为nielsbot noted,如果为函数命名,可能更容易看到上面代码的作用:
var executeSafely = function($) {
// conflict safe code =)
}
executeSafely(jQuery);
假设您的网站上有两个独立的JavaScript模块。我们假设您已经在两个js文件module-one.js
和module-two.js
中为它们编写了代码。通常情况下,页面上只有一个模块,因此在创作其中一个模块时,您并不关心另一个模块发生了什么(您甚至可能让不同的开发人员独立于另一个模块工作)。 / p>
然后,您决定在开始页面上显示这些内容会很好,所以您在首页html的head部分中包含以下内容:
<script type="text/javascript" src="module-one.js" />
<script type="text/javascript" src="module-two.js" />
[提示:世界末日音乐!] 一切都崩溃了!到底发生了什么?
您查看模块的代码,并查看以下内容:
<强>模块one.js:强>
var state = 0;
function init() {
...
}
etc...
<强>模块two.js:强>
var state = 2;
function init() {
...
}
etc ...
好吧,页面按顺序加载了两个脚本 - 首先加载了module-one.js,一切都是第一个模块;然后,加载module-two.js,覆盖第一个模块中定义的一些变量!这是因为在JavaScript中定义全局作用域中的变量,它被隐式解释为定义它window
对象。因此,如果您在彼此之后运行两个脚本文件,则首先设置window.state = 0
,然后设置window.state = 2
。如您所见,模块并非真正独立。例如,在加载两个脚本后调用init()
(或者,实际上,window.init()
)时,仅启动第二个模块 - 第一个init()
函数被覆盖(自{{ 1}}只能有一个名为window
的属性,并且不再存在。
为了避免这个问题,你应该将模块包装在函数调用中,就像上面的jQuery插件一样。但是,这些功能不需要采取任何论据:
<强>模块one.js 强>
init
<强>模块two.js 强>
(function() {
// code for module one here
})();
现在,由于这两个模块是在单独的函数中定义的,因此所有变量的作用域都只在这些函数中生效。如果您不确定如何使用JavaScript代码,将其包装在这样的函数调用中是避免冲突的好方法。因为如果你不是一直跟着它们就很难记住好的做法,所以一直跟着这个做法并不会伤害任何人=)
答案 1 :(得分:0)
这是为了保证$被分配给定义函数中的jQuery对象。他们基本上是这样做的:
var theFunction = function($){...code...};
theFunction(jQuery);
你知道吗?