理解underscore.js代码的结构

时间:2014-01-27 17:05:13

标签: javascript underscore.js

我在underscore source code 和许多其他开源JavaScript项目中看到了这种模式:

(function() {
 // the library code
}).call(this);

任何人都可以解释这种模式的作用吗?使用它有什么好处?

为什么不呢:

(function() {
 // the library code
}());

4 个答案:

答案 0 :(得分:3)

由于两者在正常情况下都是等价的,所以我查看了源代码,并在2年前将其从您建议的表单更改为当前表单,并附带以下签到注释:

“添加了与Adobe JS兼容的全局上下文的显式定义”

https://github.com/jashkenas/underscore/commit/aa916b8cfe565dc206d85c4cb74fbb6c499067a7

使用此更改的第一个版本的Underscore的登记日志声明“改进了与Adobe的JS引擎的Underscore兼容性,可用于编写Illustrator,Photoshop和朋友的脚本。”

http://underscorejs.org/版本1.4.3

所以这个改变似乎是因为当时Adobe的JavaScript引擎不符合ES3或ES5,但是通过这个改变,Underscore与他们的变体兼容。

如果您不打算在Adobe JS中运行模块,则可以使用任一表单。如果你是,那么看起来Adobe JS需要Underscore使用的表格。

答案 1 :(得分:0)

如果您碰巧同时运行多个版本的下划线,则可能与noConflict功能有关。

传递了

thiswindow),因此可以检测_的现有版本。使用这种表示法可以避免对window的硬引用,这很好。还有一些小的性能优势:局部范围内的变量解析得更快。

替代方案可能是:

(function () {
    // library
}(window)); // hard reference to window (not so nice)

(function () {
    // library
}({})); // this will break `noConflict` detection

答案 2 :(得分:0)

这是为了将整个代码包装在一个匿名函数中。这种方式在函数内声明的变量将保持私有,因此其他脚本将无法访问您的代码。

.call是一种函数方法。这将调用anonymouse函数,并将传递的参数作为值this

在这种情况下,this的值默认为window对象,将在anonymouse函数中可用。这是一个例子。

(function(a, b, c ){ // and other arguments
    // Here `this` will refer to document object.

    // And the variables declared here are compltly private

    // If you want any variable to make global use window object

    var someStuff = 'scret'; // Private

    function Lib(){
        return someStuff.length;
    }

    window.Lib = Lib; // This will be available to other scripts

}).call(document, a, b, c);

这种包装器通常由预处理器语言生成,如CoffeeScript

答案 3 :(得分:0)

第一部分

var x = 1; // `x` is in the global scope

(function() {
 var y = x; // `y` is in the current function's scope
}());

x = y; // Here `x` becomes `undefined` because `y` is not declared in this "outer" scope

关于“为什么” - 这是一种避免麻烦的简单技术(没有“内存泄漏”[函数结束时所有内部声明的变量都无效],没有声明冲突等')

第二部分: 对于call(也有类似的apply)版本,它只是一个上下文问题。
作者希望匿名函数的上下文(上面的函数)将this指向外部作用域的this

希望很清楚:)