jQuery UI 提供一套很有系統的典型物件導向開發方式

目的是讓JavaScript模組開發與重用更為簡易

jQuery UI 亦在其中建立了模組重定義 (redefining) 的機制

即開發人員可以自行建立一新模組,

並且用已經存在的模組名稱命名取代原有的模組

不管是要重寫該模組,或者是以原有模組做為基礎擴充再行取代都行

JavaScript的 OO 強化模組 ( 見此篇 ) 亦是從此機制參考修改而得

注意:此機制的建立,本意為使開發者可自由對原有模組功能擴充或加強

刪除或變更原有模組的API 在此機制下是可能的

但就模組的定位與開發上皆不是很合理的行為

原則上除非必要或情況許可,最好別這麼做

否則有可能會出現不明狀況的開發者無法預期的結果

 

因為原有模組被取代了,繼承原先模組的子模組仍舊與舊模組保持連結

使得原有的繼承樹被打亂,子模組無法享有新模組之擴充機制

因此 jQuery UI 選擇的辦法為讓子模組重新繼承新定義的模組

另一解法是完全放棄所有子模組,但是這樣有點太不人性

但無論哪種解法,都必須要得知究竟有哪些模組繼承了原有模組

jQuery UI 以一個陣列紀錄,每當有新模組繼承時

就在母模組的紀錄陣列上添加新模組的 class ( function )

並且開發者提供的 prototype 也會被記錄在新模組當中

當重新定義發生時,將陣列內的所有子模組

以各子模組紀錄的 prototype 作對自身的重新繼承

當然對子模組而言也是重新定義,因此也會觸發重新定義的連鎖

最後所有在這條鏈上的模組應會得到新模組擴充的機制

 

到這裡問題來了

假設 A 、B、C 模組皆要被重新定義

B 為 A 的子模組,B 又被 C 繼承,

那若重新定義的順序為 B → A → C

jQuery UI 的程式碼顯示

若 B 為對自己進行擴充

且新定義的 C 需要用到新定義 B 的擴充功能,結果會很糟糕

因為 B 是對自身繼承並重新定義,子模組的紀錄是會放在原有 B 模組內

接著 A 的重新定義開始進行了

那麼舊有 A 模組上面所記錄的子模組是誰呢? 仍舊是原有的 B 模組

當 A 開始重新定義後,B 模組又會被洗回原本的舊模式

這樣使得新定義的 C,會找不到新 B 模組擴充的功能而導致運作停止

 

也就是說,jQuery UI 目前的程式碼,侷限了重定義的順序

開發者必須清楚知道繼承樹的結構

但是模組一多,重新定義模組也多,這樣的錯誤是非常容易犯的

最好是能夠允許以任何順序定義

解決方法是,在 B 重新定義完成後,必須讓 A 知道 B 被重新定義過

由 A 重新紀錄新的 B 為其子模組

但是 jQuery UI 並沒有 parent 的紀錄機制

 

在 JavaScript OO 強化模組當中原先僅是為了模組追蹤才加入

在此問題後正好派上用場

但是加入此還有更多複雜事要處理,皆發生在自身擴充形式的重新定義上

首先,對自身擴充的新模組,其 parent必須記錄為原有模組的 parent

接著,依照 jQuery UI原有機制,若一個子模組被重新定義多次

每次自身擴充後模組的 prototype,皆會紀錄為最後定義的 prototype

即,當母模組重新定義發生時,只會提供最後定義的 prototype

前幾次擴充的結果都將會消失,重新繼承的結果使用時也會發生錯誤

但是這個問題因為 jQuery UI 重新定義順序的隱性強硬規定而被屏蔽

因此 OO 強化模組將 prototype 的紀錄變更

每個模組中將保留所有對自身擴充的 prototype歷史紀錄

子模組的重新定義發生時,便會將該模組的 prototype依序重新定義

雖說程序稍嫌繁雜,但是已經解決重新定義發生順序的問題

 

P.S. OO 強化模組,目前不允許重新定義的繼承目標為

自身或原有 parent以外的模組,因為不可預測性非常高

也可能造成開發者自身混亂

未來可以考慮開放可繼承原有 parent的子模組

但是這必須要做更多的模組關係檢查

arrow
arrow
    全站熱搜

    wylokgo101 發表在 痞客邦 留言(0) 人氣()