AMD(中文版)

前言

本文是源倉庫裏的AMD文檔的一份拷貝,放在這裏是用來維護歷史連接。文中任何與源倉庫裏的文檔不一致之處,以源倉庫裏的文檔爲準。git

異步模塊定義規範(AMD)制定了定義模塊的規則, 這樣模塊和模塊的依賴能夠被異步加載。這和瀏覽器的異步加載模塊的環境恰好適應(瀏覽器同步加載模塊會致使性能、可用性、調試和跨域訪問等問題。)github

此AMD與科技公司AMD及其製造的AMD處理器無關。編程

API說明

define()函數

本規範只定義了一個函數"define", 它是全局變量。函數的描述爲:api

define(id?, dependencies?, factory)複製代碼

id

第一個參數, id是個字符串。它指的是定義模塊的名字, 這個參數是可選的。若是沒有提供該參數, 模塊的名字應該默認爲模塊加載器請求的指定腳本的名字。若是提供了該參數, 模塊名必須是"頂級" 的和絕對的(不容許相對名字)。跨域

模塊名的格式

模塊名用來惟一標識定義中模塊, 它們一樣在依賴數組中使用。AMD的模塊名規範是CommonJS模塊名規範的超集。引用以下:數組

  • 模塊名是由一個或多個單詞以正斜槓爲分隔符拼接成的字符串
  • 單詞須爲駝峯形式,或者".", ".."
  • 模塊名不容許文件擴展名的形式, 如".js"
  • 模塊名能夠爲"相對的"或"頂級的"。若是首字符爲"." 或 ".."則爲"相對的"模塊名
  • 頂級的模塊名從根命名空間的概念模塊解析
  • 相對的模塊名從"require"書寫和調用的模塊解析

上文引用的CommonJS模塊id屬性常被用於JavaScript模塊。瀏覽器

相對模塊名解析示例:bash

  • 若是模塊"a/b/c"請求"../d", 則解析爲"a/d"
  • 若是模塊"a/b/c"請求"./e", 則解析爲"a/b/e"

若是AMD的實現加載器插件(Loader-Plugins), 則"!"符號用於分隔加載器插件模塊名和插件資源名。因爲插件資源名能夠很是自由地命名,大多數字符都容許在插件資源名使用。異步

(譯註: 關於Loader-Plugins)函數

依賴

  • 第二個參數, dependdencies是個定義中模塊所依賴模塊的數組。依賴模塊必須根據模塊的工廠方法優先級執行,而且執行的結果應該按照依賴數組中的位置順序以參數的形式傳入(定義中模塊的)工廠方法中。
    依賴的模塊名若是是相對的,應該解析爲相對定義中的模塊。換句話來講,相對名解析爲相對於模塊的名字,並不是相對於尋找該模塊的名字的路徑。

  • 本規範定義了三種特殊的依賴關鍵字。若是"require", "exports", 或"module"出如今依賴列表中, 參數應該按照CommonJS模塊規範自由變量去解析。

  • 依賴參數是可選的,若是忽略此參數,它應該默認爲["require", "exports", "module"]。然而,若是工廠方法的形參個數小於3,加載器會選擇以函數指定的參數個數調用工廠方法。

工廠方法

第三個參數, factory, 爲模塊初始化要執行的函數或對象。若是爲函數, 它應該只被執行一次。若是是對象,此對象應該爲模塊的輸出值。

若是工廠方法返回一個值(對象, 函數, 或任意強制類型轉換爲true的值), 應該爲設置爲模塊的輸出值。

簡單的CommonJS轉換

  • 若是依賴性參數被忽略,模塊加載器能夠選擇掃描工廠方法中的require語句得到依賴性(字面量形參爲require("module-id"))。 第一個參數必須字面量爲require從而使此機制正常工做。
  • 在某些狀況下,由於腳本大小的限制或函數不支持toString方法(Opera Mobile是已知的不支持函數的toString方法),模塊加載器能夠選擇掃描不掃描依賴性。
  • 若是有依賴參數, 模塊加載器不該該在工廠方法中掃描依賴性。

define.amd屬性

  • 爲了清晰的標識全局函數(爲瀏覽器加載script必須的)聽從AMD編程接口, 任何全局函數應該有一個"amd"的屬性, 它的值爲一個對象。這樣能夠防止與現有的定義了define函數但不聽從AMD編程接口的代碼相沖突。

  • 當前,define.amd對象的屬性沒有包含在本規範中。實現本規範的做者,能夠用它通知超出本規範編程接口基本實現的額外能力。

  • define.amd的存在代表函數遵循本規範。若是有另一個版本的編程接口,那麼應該定義另一個屬性,如define.amd2, 代表實現只遵循該版本的編程接口。

一個若是定義同一個環境中容許屢次加載同一個版本的模塊的實現:

define.amd = {
        multiversion: true
    }複製代碼

最簡單的定義:

define.amd = {}複製代碼

一次輸出多個模塊

在一個腳本中可使用屢次define調用。這些define調用的順序不該該是重要的。早一些的模塊定義中所指定的依賴,能夠在同一腳本中晚一些定義。模塊加載器負責延遲加載未接解決的依賴,直到所有腳本加載完畢,防止不必的請求。

例子

使用require和exports

建立一個名爲"alpha"的模塊,使用了require, exports和名爲"beta"的模塊:

define("alpha", ["require", "exports", "module"], function (require, exports, beta) {
        exports.verb = function () {
            return beta.verb()
            // Or:
            return requre("beta").verb()
        }
    })複製代碼

一個返回對象的匿名模塊:

define(["alpha"], function (alpha) {
        return {
            verb: function () {
                return alpha.verb() + 2
            }
        }
    })複製代碼

一個沒有依賴性的模塊能夠直接定義對象:

define({
        add: function (x, y) {
            return x + y
        }
    })複製代碼

一個使用了簡單CommonJS轉換的模塊定義:

define(function(require, exports, module) {
    var a = require("a")
        b = require("b")

    exports.action = function () {}    
})複製代碼

全局變量

本規範保留全局變量"define"以用來實現本規範。包額外信息異步定義編程接口是未未來的CommonJS API保留的。模塊加載器不該在此函數添加額外的方法或屬性。

本規範保留全局變量"require"被模塊加載器使用。模塊加載器能夠在合適的狀況下自由地使用該全局變量。它可使用這個變量或添加任何屬性以完成模塊加載器的特定功能。它一樣也能夠選擇徹底不使用"require"。

使用注意

爲了使靜態分析工具(若是build工具)能夠正常工做,推薦使用字面上形如的"define(...)"。

與CommonJS的關係

一個關於本API的wiki開始在CommonJS wiki中建立了,做爲中轉的格式,模塊中轉。可是爲了包含模塊定義接口,隨着時間而不斷改變。在CommonJS列表中關於推薦本API做爲模塊定義API還沒有達成一致。本API被轉移到它本身的wiki和討論組中。

AMD能夠做爲CommonJS模塊一箇中轉的版本只要CommonJS沒有被用來同步的require調用。使用同步require調用的CommonJS代碼能夠被轉換爲使用回調風格的AMD模塊加載器。

感言

本人只是一個搬運工, 若有不符之處請指出,寫博客的做用只是爲了複習基礎(好記性不如爛筆頭)。這是寫的第一篇博文,後續會有各類基礎的博文,若是有需求的能夠關注。

(不符之處請發郵箱: unknown_xxx@163.com, 會進行修改,謝謝。)

相關文章
相關標籤/搜索