`
k1280000
  • 浏览: 203750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Js code : Module Utilities

 
阅读更多

This section presents an extended example (Example 10-5 ) of a module of module-related utilities. The Module.createNamespace( ) utility handles namespace creation and error checking. A module author might use it like this:

// Create a namespace for our module
Module.createNamespace("com.davidflanagan.Class");

// Now start populating the namespace
com.davidflanagan.Class.define = function(data) { /* code here */ };
com.davidflanagan.Class.provides = function(o, c) { /* code here */ };

 

The Module.require( ) function checks for the presence of the specified version (or later) of a named module and throws an error if it does not exist. Use it like this:

// This Complex module requires the Class module to be loaded first
Module.require("com.davidflanagan.Class", 1.0);

 

The Module.importSymbols( ) function simplifies the task of importing symbols into the global namespace or another specified namespace. Here are examples of its use:

// Import the default set of Module symbols to the global namespace
// One of these defualt symbols is importSymbols itself
Module.importSymbols(Module); // Note we pass the namespace, not module name

// Import the Complex class into the global namespace
importSymbols(com.davidflanagan.Complex);

// Import the com.davidflanagan.Class.define( ) method to a Class object
var Class = {};
importSymbols(com.davidflanagan.Class, Class, "define");

 

Finally, the Module.registerInitializationFunction( ) allows a module to register a function of initialization code to be run at some later time.[*] When this function is used in client-side JavaScript, an event handler is automatically registered to invoke all initialization functions for all loaded modules when the document finishes loading. When used in other, nonclient-side contexts, the initialization functions are not automatically invoked, but can be explicitly invoked with Module.runInitializationFunctions( ) .

[*] See also Example 17-6 for a similar initialization function registration utility.

The Module module is shown in Example 10-5 . This example is a long one, but the code repays careful study. Documentation and full details of each utility function are found in the code.

 

 

 

/**
 * Module.js: module and namspace utilities
 *
 * This is a module of module-related utility functions that are
 * compatible with JSAN-type modules.
 * This module defines the namespace Module.
 */

// Make sure we haven't already been loaded
var Module;
if (Module && (typeof Module != "object" || Module.NAME))
    throw new Error("Namespace 'Module' already exists");

// Create our namespace
Module = {};

// This is some metainformation about this namespace
Module.NAME = "Module";    // The name of this namespace
Module.VERSION = 0.1;      // The version of this namespace

// This is the list of public symbols that we export from this namespace.
// These are of interest to programers who use modules.
Module.EXPORT = ["require", "importSymbols"];

// These are other symbols we are willing to export. They are ones normally
// used only by module authors and are not typically imported.
Module.EXPORT_OK = ["createNamespace", "isDefined",
                    "registerInitializationFunction",
                    "runInitializationFunctions",
                    "modules", "globalNamespace"];


// Now start adding symbols to the namespace
Module.globalNamespace = this;  // So we can always refer to the global scope
Module.modules = { "Module": Module };  // Module name->namespace map.

/**
 * This function creates and returns a namespace object for the
 * specified name and does useful error checking to ensure that the
 * name does not conflict with any previously loaded module. It
 * throws an error if the namespace already exists or if any of the
 * property components of the namespace exist and are not objects.
 *
 * Sets a NAME property of the new namespace to its name.
 * If the version argument is specified, set the VERSION property
 * of the namespace.
 *
 * A mapping for the new namespace is added to the Module.modules object
 */
Module.createNamespace = function(name, version) {
    // Check name for validity.  It must exist, and must not begin or
    // end with a period or contain two periods in a row.
    if (!name) throw new Error("Module.createNamespace( ): name required");
    if (name.charAt(0) == '.' ||
        name.charAt(name.length-1) == '.' ||
        name.indexOf("..") != -1)
        throw new Error("Module.createNamespace( ): illegal name: " + name);

    // Break the name at periods and create the object hierarchy we need
    var parts = name.split('.');

    // For each namespace component, either create an object or ensure that
    // an object by that name already exists.
    var container = Module.globalNamespace;
    for(var i = 0; i < parts.length; i++) {
        var part = parts[i];
        // If there is no property of container with this name, create
        // an empty object.
        if (!container[part]) container[part] = {};
        else if (typeof container[part] != "object") {
            // If there is already a property, make sure it is an object
            var n = parts.slice(0,i).join('.');
            throw new Error(n + " already exists and is not an object");
        }
        container = container[part];
    }

    // The last container traversed above is the namespace we need.
    var namespace = container;

    // It is an error to define a namespace twice. It is okay if our
    // namespace object already exists, but it must not already have a
    // NAME property defined.
    if (namespace.NAME) throw new Error("Module "+name+" is already defined");

    // Initialize name and version fields of the namespace
    namespace.NAME = name;
    if (version) namespace.VERSION = version;

    // Register this namespace in the map of all modules
    Module.modules[name] = namespace;

    // Return the namespace object to the caller
    return namespace;
}
/**
 * Test whether the module with the specified name has been defined.
 * Returns true if it is defined and false otherwise.
 */
Module.isDefined = function(name) {
    return name in Module.modules;
};

/**
 * This function throws an error if the named module is not defined
 * or if it is defined but its version is less than the specified version.
 * If the namespace exists and has a suitable version, this function simply
 * returns without doing anything. Use this function to cause a fatal
 * error if the modules that your code requires are not present.
 */
Module.require = function(name, version) {
    if (!(name in Module.modules)) {
        throw new Error("Module " + name + " is not defined");
    }

    // If no version was specified, there is nothing to check
    if (!version) return;

    var n = Module.modules[name];

    // If the defined version is less than the required version or if
    // the namespace does not declare any version, throw an error.
    if (!n.VERSION || n.VERSION < version)
    throw new Error("Module " + name + " has version " +
                    n.VERSION + " but version " + version +
                    " or greater is required.");
};

/**
 * This function imports symbols from a specified module.  By default, it
 * imports them into the global namespace, but you may specify a different
 * destination as the second argument.
 *
 * If no symbols are explicitly specified, the symbols in the EXPORT
 * array of the module will be imported. If no such array is defined,
 * and no EXPORT_OK is defined, all symbols from the module will be imported.
 *
 * To import an explicitly specified set of symbols, pass their names as
 * arguments after the module and the optional destination namespace. If the
 * modules defines an EXPORT or EXPORT_OK array, symbols will be imported
 * only if they are listed in one of those arrays.
 */
Module.importSymbols = function(from) {
    // Make sure that the module is correctly specified. We expect the
    // module's namespace object but will try with a string, too
    if (typeof from == "string") from = Module.modules[from];
    if (!from || typeof from != "object")
        throw new Error("Module.importSymbols( ): " +
                        "namespace object required");

    // The source namespace may be followed by an optional destination
    // namespace and the names of one or more symbols to import;
    var to = Module.globalNamespace; // Default destination
    var symbols = [];                // No symbols by default
    var firstsymbol = 1;             // Index in arguments of first symbol name

    // See if a destination namespace is specified
    if (arguments.length > 1 && typeof arguments[1] == "object") {
        if (arguments[1] != null) to = arguments[1];
        firstsymbol = 2;
    }

    // Now get the list of specified symbols
    for(var a = firstsymbol; a < arguments.length; a++)
        symbols.push(arguments[a]);

    // If we were not passed any symbols to import, import a set defined
    // by the module, or just import all of them.
    if (symbols.length == 0) {
        // If the module defines an EXPORT array, import
        // the symbols in that array.
        if (from.EXPORT) {
            for(var i = 0; i < from.EXPORT.length; i++) {
                var s = from.EXPORT[i];
                to[s] = from[s];
            }
            return;
        }
        // Otherwise if the modules does not define an EXPORT_OK array,
        // just import everything in the module's namespace
        else if (!from.EXPORT_OK) {
            for(s in from) to[s] = from[s];
            return;
        }
    }

    // If we get here, we have an explicitly specified array of symbols
    // to import. If the namespace defines EXPORT and/or EXPORT_OK arrays,
    // ensure that each symbol is listed before importing it.
    // Throw an error if a requested symbol does not exist or if
    // it is not allowed to be exported.
    var allowed;
    if (from.EXPORT || from.EXPORT_OK) {
        allowed = {};
        // Copy allowed symbols from arrays to properties of an object.
        // This allows us to test for an allowed symbol more efficiently.
        if (from.EXPORT)
            for(var i = 0; i < from.EXPORT.length; i++)
                allowed[from.EXPORT[i]] = true;
        if (from.EXPORT_OK)
            for(var i = 0; i < from.EXPORT_OK.length; i++)
                allowed[from.EXPORT_OK[i]] = true;
    }

    // Import the symbols
    for(var i = 0; i < symbols.length; i++) {
        var s = symbols[i];              // The name of the symbol to import
        if (!(s in from))                // Make sure it exists
            throw new Error("Module.importSymbols( ): symbol " + s +
                            " is not defined");
        if (allowed && !(s in allowed))  // Make sure it is a public symbol
            throw new Error("Module.importSymbols( ): symbol " + s +
                            " is not public and cannot be imported.");
        to[s] = from[s];                 // Import it
    }
};


// Modules use this function to register one or more initialization functions
Module.registerInitializationFunction = function(f) {
    // Store the function in the array of initialization functions
    Module._initfuncs.push(f);
    // If we have not yet registered an onload event handler, do so now.
    Module._registerEventHandler( );
}
// A function to invoke all registered initialization functions.
// In client-side JavaScript, this will automatically be called in
// when the document finished loading. In other contexts, you must
// call it explicitly.
Module.runInitializationFunctions = function( ) {
    // Run each initialization function, catching and ignoring exceptions
    // so that a failure by one module does not prevent other modules
    // from being initialized.
    for(var i = 0; i < Module._initfuncs.length; i++) {
        try { Module._initfuncs[i]( ); }
        catch(e) { /* ignore exceptions */}
    }
    // Erase the array so the functions are never called more than once.
    Module._initfuncs.length = 0;
}

// A private array holding initialization functions to invoke later
Module._initfuncs = [];

// If we are loaded into a web browser, this private function registers an
// onload event handler to run the initialization functions for all loaded
// modules. It does not allow itself to be called more than once.
Module._registerEventHandler = function( ) {
    var clientside =   // Check for well-known client-side properties
        "window" in Module.globalNamespace &&
        "navigator" in window;

    if (clientside) {
        if (window.addEventListener) {  // W3C DOM standard event registration
            window.addEventListener("load", Module.runInitializationFunctions,
                                    false);
        }
        else if (window.attachEvent) {  // IE5+ event registration
            window.attachEvent("onload", Module.runInitializationFunctions);
        }
        else {
            // IE4 and old browsers
            // If the <body> defines an onload tag, this event listener
            // will be overwritten and never get called.
            window.onload = Module.runInitializationFunctions;
        }
    }

    // The function overwrites itself with an empty function so it never
    // gets called more than once.
    Module._registerEventHandler = function( ) {};
}

 

 

分享到:
评论

相关推荐

    Microsoft Codeview and Utilities User's Guide

    Microsoft Codeview and Utilities User's Guide Microsoft(R) CodeView(R) and Utilities User's Guide Version 2.3 for MS(R) OS/2 and MS-DOS(R) Operating Systems MICROSOFT CORPORATION Information in ...

    module-textalk:DAISY Pipeline 2模块,包含用于测试如何编写模块的脚本

    在给定的标题和描述中,"module-textalk"是一个特定的DAISY Pipeline 2模块,其目的是为开发者提供编写新模块的测试和示例脚本。 **XProc:XML 过程语言** XProc(XML Processing)是一种W3C推荐的标准,用于定义...

    TuneUp Utilities 2010官方简体中文注册版

    TuneUp Utilities是一款源自德国的全方位系统优化软件,专为提升计算机性能、改善系统稳定性及清理无用文件而设计。2010版是该系列的一个重要版本,提供了多语言支持,包括简体中文,使得中国用户能够更加方便地使用...

    Java.Threads.and.the.Concurrency.Utilities.1484216997

    This concise book empowers all Java developers to master the complexity of the Java thread APIs and concurrency utilities. This knowledge aids the Java developer in writing correct and complex ...

    tabutils:Tab Utilities的兼容性修补程序版本

    选项卡实用程序已修复(不建议使用) 的兼容性修补程序已发布。 该项目的重点目标:Firefox 28(带有橙色的“ Firefox”按钮或Pale Moon)与最新的Firefox Beta(已针对Windows测试)的兼容性修补程序。...

    DatabaseUtilities

    《数据库工具库——DatabaseUtilities在C#开发中的应用》 在软件开发过程中,数据库操作是不可或缺的一部分,尤其是在C#环境中,高效、稳定的数据库交互对于提升应用程序的性能和用户体验至关重要。"Database...

    MySQL管理工具MySQL Utilities v1.6.5 64-bit

    MySQL Utilities 提供一组命令行工具用于维护和管理 MySQL 服务器,包括: 管理工具 (克隆、复制、比较、差异、导出、导入) 复制工具 (安装、配置) 一般工具 (磁盘使用情况、冗余索引、搜索元数据) Tags: MySQL ...

    Docutils: Documentation Utilities-开源

    这个项目的全称是“Documentation Utilities”,正如其名,它的主要功能是为文档处理提供了一系列实用程序,支持从源文件到多种格式的转换,如HTML、PDF、XML等。 在Docutils中,reStructuredText(简称reST)是...

    Norton Utilities V5.0

    《Norton Utilities V5.0:DOS时代的经典磁盘与文件管理利器》 Norton Utilities V5.0,作为一款在DOS操作系统时代极具影响力的软件,它集合了一系列强大的磁盘管理和系统优化工具,为当时的计算机用户提供了...

    aws_utilities:aws 实用程序

    4. **Node.js**: AWS Utilities 通常会运行在 Node.js 环境下,这是一个开放源代码、跨平台的 JavaScript 运行时环境,可以让开发者在服务器上执行 JavaScript 代码。 5. **Git仓库结构**:“aws_utilities-master...

    Glary_Utilities_4.6.0.90最新版注册码

    Glary Utilities是一款全方位的系统优化工具集合,能够帮助用户清理无用文件、修复注册表错误、优化内存、管理和删除不必要的启动项等。它支持一键式操作,简化了复杂的维护任务,使得无论是电脑新手还是高级用户都...

    ovr_unity_utilities_1.13.0

    "ovr_unity_utilities_1.13.0" 是一套专为Unity开发虚拟现实(VR)应用而设计的工具包,由Oculus提供。这个版本是1.13.0,表明它经过了多次迭代和优化,以适应开发者的需求。Oculus Utilities包含了多种实用功能,旨在...

    UtilitiES UtilitiES UtilitiES

    UtilitiES UtilitiES UtilitiES UtilitiES UtilitiES

    iris-utilities:IRIS Utilities是一款多功能不和谐机器人,可让您播放音乐,娱乐并执行各种其他与实用程序相关的事情

    IRIS Utilities是一款多功能Discord机器人,可让您播放音乐,娱乐并执行各种其他与实用程序有关的任务。 IRIS代表什么? IRIS是交互式侦察信息服务机构,她在这里为您提供帮助! 为什么IRIS Utilities是“她”? ...

    mysql-utilities-1.3.6-win32.msi

    MySQL Utilities provides a collection of command-line utilities that are used for maintaining and administering MySQL servers, including: Admin Utilities (Clone, Copy, Compare, Diff, Export, Import) ...

    cwutils:CoastWatch Utilities软件,用于处理来自NOAA CoastWatch和其他地方的卫星数据文件

    CoastWatch Utilities使您可以处理由美国商务部的程序NOAA CoastWatch / OceanWatch创建的地球科学数据。 您可以轻松查看和转换各种格式的数据:HDF 4,NOAA 1b和带有CF元数据的NetCDF 4(最后一种格式是许多组织...

    Halcyon:Halcyon Utilities,这是 Apache Commons Lang3 的补充实用程序

    宁静Halcyon Utilities,Apache Commons Utilities 的瘦补充实用程序这些实用程序并非旨在用于避免执行空检查和捕获异常。-- API 在首次发布版本之前可能会发生变化!用例LDAP 目录字符串 ( 定义属性中必须有一个或...

    TuneUp Utilities 2009

    官方描述:TuneUp Utilities 2009 can quickly make your Windows operating system faster, easier to use, and more secure. And all operations performed on the operating system are completely safe, because ...

    TuneUp.Utilities.2009

    《TuneUp Utilities 2009:电脑优化与维护的全方位指南》 TuneUp Utilities 2009是一款著名的系统优化软件,专为Windows操作系统设计,旨在提升电脑性能、改善系统稳定性和节省硬盘空间。它集合了多种实用工具,...

    TuneUp Utilities 2011简体中文注册版 分卷1

    TuneUp Utilities软件简介 TuneUp Utilities 是你PC的瑞士军刀——德国系统调校工具第一品牌 TuneUp Utilities,能优化系统性能、解决问题并帮助你定制系统,以满足你的需要!通过 TuneUp Utilities, 你能使 Windows ...

Global site tag (gtag.js) - Google Analytics