顯示廣告
隱藏 ✕
※ 本文為 dinos.bbs. 轉寄自 ptt.cc 更新時間: 2012-07-14 07:12:03
看板 Ajax
作者 mrbigmouth (拒絕崩潰的蒲公英)
標題 Re: [問題] (...)()或(...)(window)是什麼意思?
時間 Sat Jul 14 00:56:33 2012


※ 引述《cyutdt (DT)》之銘言:
: 常在程式看到
: (function() {
:     ...
: })();
: 或
: (function() {
:     ...
: })(window);
: 我已經看過closure的相關教學和討論
: 還是不曉得這跟closure是否有關聯
: 還是跟$(document).ready(function(){});有什麼關係呢?
: 看到一些這種範例
: 不曉得為什麼要這樣寫

雖然我覺得google一定找得到答案
但現在剛好無聊就來說一說我的理解好了
如有錯誤煩請指證

(function() {})()
上面這種格式
就是所謂的self invoking anonymous function
     自我 執行   匿名   函數
在程式邏輯上是"製造一個匿名的函數並且立刻執行"
其目的主要在於產生一個私有的scope,使在其內宣告的變數不會與外界混淆

以我最常使用的格式為例,會在寫一些獨立運行的網頁程式的一開始寫出如下的宣告

(function(window) {
    var document = window.document,
        $ = window.jQuery,
        variableA,
        variableB,
        variableC,
        .
        .
        .
        variableN;

    //下面才開始寫程式

    //寫到這裡結束程式

    //如果有必要,將需要輸出的函式/功能指派到window下的廣域變數
    window.OOXX = variable???;
})(window);

這樣做最主要的好處在於,
在這個裡面所宣告的變數絕對不會被外界的變數干擾(因為指不到),
不管該網頁引入了多少library、後來者又亂插入了多少script、
server或使用者瀏覽器亂安裝的plugin在網頁後方又加了什麼奇怪的壞掉script....
我寫在這個scope裡的區域變數都絕對不可能會被影響到,
也因此保證了我寫出的這個獨立運作的程式在自己運作時絕對不會有問題。
同時,一些用過即丟的變數也不會一直掛在廣域環境下佔記憶體,
因為全部的變數都是區域變數,使用google closure compiler等軟體進行minify化
時也能省掉更多的空間

至於在後方的括號裡丟入window,
是為了增加讀取的速度。
這裡的相關關鍵字叫做Scope Chain。

當你使用一個變數時,若javascript在當前環境找不到該名稱的變數,
就會繼續往外找尋,一直找到最外層的全域物件上還找不到時,才會報錯

而大家都知道,目前所有瀏覽器的全域物件都叫window。
所有你宣告的廣域函式跟變數都會掛在window下,
如果你想在上面的self invoking function裡使用任何廣域變數,
javascript就得多經過一次的「找不到的過程」才能找到。
但是只要你把window當成參數丟進你的self invoking function裡面,
window就會變成你自製scope裡的區域變數,
於是就省下了一層查找的功夫。
雖然我也很懷疑到底等省下多少功夫啦
但多丟參數畢竟只是動幾下手指的事而已。

而一些其他的變種
(function (window, undefined){

})(window)

在scope裡宣告了undefined這個變數,
但是在自我執行時又不丟給他,
如此便能夠完全確定你在使用undefined時代表的真的是undefined,
(是的,undefined是可以改變值的)

而這種
(function ($){

})(jQuery)
跟傳window進去的意義是一樣的
會這樣使用的人應該是認為他在這個scope裡面使用到的廣域變數只有jQuery一個,
所以只丟jQuery進去,省去了在scope裡面再次宣告的功夫。

另外,jQuery的$縮寫是有可能改變的,
(通常在你同時使用其他以$為縮寫的library時)
因此這種方法也兼顧了相容性。

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 1.164.71.67

--
※ 看板: dinos 文章推薦值: 0 目前人氣: 0 累積人氣: 291 
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇