2011-04-18 55 views
5

http://a2.twimg.com/a/1302724321/javascripts/widgets/widget.js?1302801865幫助理解twitters widget.js文件,封閉內的閉包?

這是設置這樣在較高的水平:

公共命名空間:

TWTR = window.TWTR || {}; 

然後封閉:

(function() { 
... 

})(); // #end application closure 

在應用程序關閉:

TWTR.Widget = function(opts) { 
    this.init(opts); 
}; 
(function() { 
    // Internal Namespace. 
    var twttr = {}; 
})(); 

某些方法被標記爲公共,其他方法是私有的,唯一的區別似乎是命名約定(私有以下劃線'_'開頭)。

是否使用模塊模式設計?

爲什麼或者在關閉時關閉關閉會帶來什麼好處?

因爲他們在jquery之前加載widget.js,這意味着小部件被設計爲運行無w/o jquery,因爲順序是正確的?

只是試圖從這件事情中學習!

+0

那些不是_exactly_ [閉包](http://en.wikipedia.org/wiki/Closure_%28computer_science%29)。這些是[自我調用函數](http://2007-2010.lovemikeg.com/2008/08/17/a-week-in-javascript-patterns-self-invocation/),如果它們使用_might可以創建閉包_在其功能範圍之外定義的變量。 [這是一個很好的描述](http://blog.morrisjohns.com/javascript_closures_for_dummies.html)實際上是什麼閉包:_「一個函數的局部變量 - 在函數返回後保持活動狀態。」_ – 2011-04-18 04:19:47

+0

另一個好東西閱讀閉包:[/ b] http://shackoverflow.com/questions/111102/](http://stackoverflow.com/questions/111102/) – 2011-04-18 04:23:16

+0

btw,其中this.init(..)函數定義? – Blankman 2011-04-18 13:57:46

回答

4

正是這樣的設置在較高的水平:

公共命名空間:

TWTR = window.TWTR || {};

這是不好的編碼習慣,變量應該是總是被聲明爲var。並且在JavaScript中沒有「名稱空間」,該術語適用於上述構造,但它並不合適。更好地說,它的方法是由一個對象包含的。

然後封閉:

> (function() { ... 
> 
> })(); // #end application closure 

這種模式已經到了被稱爲立即調用函數表達式iife。不知道我喜歡這個名字,但是你去了。無論如何,它不一定會產生任何有用的關閉。閉包只有在函數創建變量綁定到其他執行上下文時纔有用,該上下文超出了創建它們的函數的生命期(我希望它不像gobbledy-goop)。你不需要一個iif來創建一個閉包。

但是,您可以使用上述模式創建閉包,因爲它與其他函數非常相似。

在應用程序關閉:

> TWTR.Widget = function(opts) { 
>  this.init(opts); }; (function() { 
>  // Internal Namespace. 
>  var twttr = {}; })(); 

一些方法標記爲公共,他人 私人,唯一的區別似乎 是命名約定(私人 開始用下劃線「 _')。

使用「public」和「private」在javascript中有點誤導。使用下劃線來啓動標識符名稱表明應僅在當前範圍內使用,或者由「庫」代碼本身使用。這是有點多餘的,因爲代碼應該有一個公開的API,任何不屬於API的方法都不應該在外部可用。

但這在很大程度上是編碼風格和個人偏好的問題。

它是使用模塊模式設計的嗎?

理查德康福德的「模塊模式」就是這樣一種模式。在JavaScript中模擬「私有」變量非常方便,並且除了通常的原型繼承外,還可以在函數或方法之間共享屬性。 widget.js可以使用模塊模式實現(部分),但它可能是通過考慮需求和功能來設計的。 ;-)

爲什麼或者在閉包中關閉時獲得什麼好處?

與上述任何關閉完全相同的好處。本質上通過將它們放在作用域鏈的適當部分來訪問變量基本上與通過[[prototype]]鏈訪問屬性相同,只有(非常不同的)機制 - 一個使用作用域鏈上的標識符解析,另一個屬性決議[[原型]]鏈。

編輯

的一個缺點是整個激活對象的封閉變量屬於很可能保留在內存中,所以如果你只需要訪問一個共享變量,不如考慮一些其他的方案,甚至可能是經典的原型繼承。或者至少如果你打算使用閉包,儘量保持相關的激活對象儘可能小(例如,設置任何在退出前不使用的變量)。

例如

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

由於他們的jQuery之前裝入widget.js,這意味着小部件被設計爲運行W/O jQuery的,因爲爲了事項是否正確?

我現在無法訪問鏈接資源(公司阻止推特域),但加載順序表明您是正確的。但是,有些代碼執行可能會延遲,直到文檔被完全加載,所以它不是一個保證,你需要看代碼。

+0

謝謝! btw,where.init(..)在哪裏定義?我看不到它! – Blankman 2011-04-18 13:58:01