帮助理解twitters widget.js文件,一个闭包内的闭包?

Bla*_*man 5 javascript twitter jquery

http://a2.twimg.com/a/1302724321/javascripts/widgets/widget.js?1302801865

它在这样的高级别设置:

public namespace:

TWTR = window.TWTR || {};
Run Code Online (Sandbox Code Playgroud)

然后关闭:

(function() {
...

})(); // #end application closure
Run Code Online (Sandbox Code Playgroud)

在应用程序闭包内:

TWTR.Widget = function(opts) {
    this.init(opts);
};
(function() {
    // Internal Namespace.
    var twttr = {};
})();
Run Code Online (Sandbox Code Playgroud)

有些方法标记为public,其他方法为private,唯一的区别似乎是命名约定(私有以下划线'_'开头).

它是使用模块模式设计的吗?

封闭内闭合的原因是什么或有什么好处?

因为他们在jquery之前加载widget.js,这意味着widget被设计为运行w/o jquery,因为顺序重要吗?

只是想从这个东西中学习!

Rob*_*obG 4

它的高级设置如下:

公共命名空间:

TWTR = 窗口.TWTR || {};

这是不好的编码习惯,变量应该总是用 var 声明。javascript 中没有“命名空间”,该术语适用于上述构造,但实际上并不合适。更好的说法是它的方法包含在一个对象中。

然后是一个闭包:

> (function() { ...
> 
> })(); // #end application closure
Run Code Online (Sandbox Code Playgroud)

该模式被称为立即调用函数表达式iife。不确定我喜欢这个名字,但你就知道了。无论如何,它并不一定会创建任何有用的闭包。仅当函数创建的变量绑定到其他执行上下文,且这些执行上下文在创建它们的函数的生命周期结束后仍存在时,闭包才有用(我希望这看起来不像官样文章)。您不需要iife来创建闭包。

但是,您可以使用上面的模式来创建闭包,因为它是一个与任何其他函数非常相似的函数。

在应用程序关闭内:

> TWTR.Widget = function(opts) {
>     this.init(opts); }; (function() {
>     // Internal Namespace.
>     var twttr = {}; })();
Run Code Online (Sandbox Code Playgroud)

有些方法被标记为公共,其他方法被标记为私有,唯一的区别似乎是命名约定(私有以下划线“_”开头)。

在 JavaScript 中使用“public”和“private”有点误导。使用下划线开始标识符名称表示仅应在当前范围内使用或由“库”代码本身使用。这有点多余,因为代码应该有一个已发布的 API,并且任何不属于 API 的方法都不应该在外部可用。

但这很大程度上取决于编码风格和个人喜好。

是采用模块模式设计的吗?

Richard Cornford 的“模块模式”就是这样一种模式。它可以方便地模拟 JavaScript 中的“私有”变量,也可以在函数或方法之间共享属性,而不是通过通常的原型继承。widget.js 可能(部分)使用模块模式实现,但它很可能是通过考虑需求和功能来设计的。;-)

为什么使用闭包中的闭包可以获得什么好处?

与上述任何关闭的好处完全相同。通过将变量放置在作用域链的适当部分来访问变量本质上与通过 [[prototype]] 链访问属性基本相同,只是使用(非常不同的)机制 - 一个在作用域链上使用标识符解析,另一个使用属性[[prototype]]链上的决议。

编辑

一个缺点是封闭变量所属的整个激活对象可能保留在内存中,因此如果您只需要访问共享变量,最好考虑其他方案,甚至可能是经典的原型继承。或者至少如果您要使用闭包,请尝试使相关的激活对象尽可能小(例如,在退出之前将不使用的任何变量设置为 null)。

例如

var foo = (function() {

  // Variables available for closure
  var a, b, c;

  // Use a, b, c for stuff
  ...

  // Only want closure to c
  a = null;
  b = null;

  return function() {
    // use c
  }
}());
Run Code Online (Sandbox Code Playgroud)

由于它们在 jquery 之前加载 widget.js,这意味着 widget 被设计为无需 jquery 即可运行,因为顺序很重要?

我现在无法访问链接的资源(Twitter 域的公司阻止),但加载顺序表明您是正确的。但是,某些代码的执行可能会延迟到文档完全加载为止,因此这不能保证,您需要查看代码。