CoffeeScript 裡的全域變數

在 CoffeeScript 裡,即使是一個空的 .coffee 檔,它也會被編譯成這樣:

(function() {

}).call(this);

你在 .coffee 寫的任何變數或 function,都是被宣告為區域變數包在裡面,只會在裡面有作用而已。這其實是好事,因為這樣一來與外界隔離,你寫的東西不會去污染到別人寫的,相對的別人寫的東西也不會去弄髒你寫的。但假設因為某些不可抗力,硬是要把變數或 function 弄成 global 好讓所有頁面都可以直接使用,也不是沒辦法,你可以直接把變數或 function 掛在window物件底下:

window.logout = ->
alert "You've already logout!" if confirm "Are you sure to logout?"

或是這樣做:

root = exports ? this
root.logout = ->
alert "You've already logout!" if confirm "Are you sure to logout?"

第二種寫法看起來比較麻煩,但比較通用。exports 是在Node.js裡定義的物件,上面第 1 行的意思是指會先檢查 exports 是不是已經有定義了,如果這段程式是在 Node.js 裡執行的話,因為 exports 是存在的,所以會定義一個 root 變數並指向它;如果是在一般的網頁上執行,因為沒有 exports,所以會定義一個 root 指向 this,也就是 window 物件 ,所以這樣的寫法的好處就是在網頁或是 Node.js 都行得通。

這樣一來,你在頁面上的按鈕就可以這樣寫:

<input type="button" value="logout" id="Logout" onclick="logout();" />

但是,如果可以的話,建議還是儘量避免用這種 global 變數的方式來寫程式,現在的 JavaScript 越寫越複雜,沒人知道你寫的東西會不會剛好就去衝到誰家寫的 library,或是衝到你自己或同事寫的程式碼 :)