- 浏览: 2683374 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
80后的童年2:
深入浅出MongoDB应用实战开发网盘地址:https://p ...
MongoDB入门教程 -
shliujing:
楼主在不是精通java和php的前提下,请不要妄下结论。
PHP、CakePHP哪凉快哪呆着去 -
安静听歌:
希望可以一给一点点注释
MySQL存储过程之代码块、条件控制、迭代 -
qq287767957:
PHP是全宇宙最强的语言!
PHP、CakePHP哪凉快哪呆着去 -
rryymmoK:
深入浅出MongoDB应用实战开发百度网盘下载:链接:http ...
MongoDB入门教程
JavaScript是世界上最被误解的编程语言
由于JavaScript的简单易用,它往往被认为是美工MM们的专属天使
dlee曾经说过,那些至今还认为JavaScript不是一门编程语言的人是xx的
虽然JavaScript发展了十几年,但目前许多现代编程语言的普遍特性还不完全具备,比如namespace/package
现如今JavaScript的广泛使用导致了许多框架级产物如雨后春笋般遍地开花,JavaScript库也亟需namespace/package这种特性支持
而当我们使用第三方库时,如果没有良好的namespace/package支持,我们也很容易陷入变量和函数重名的痛苦(比如jQuery和Prototype的“$”)
让我们先来看看简单的namespace/package实现:
十分麻烦!
让我们创建一个辅助文件Module.js来帮助我们创建名字空间:
我们这样使用Module辅助对象:
这样果然方便多了!
还有一些开源的JavaScript包管理工具,如jspkg
Mozilla的JavaScript 2.0 proposal和ECMAScript 4 Proposal都在JavaScript核心语法里添加了Namespaces和Packages功能
注:文中部分代码来自《JavaScript: The Definitive Guide》
由于JavaScript的简单易用,它往往被认为是美工MM们的专属天使
dlee曾经说过,那些至今还认为JavaScript不是一门编程语言的人是xx的
虽然JavaScript发展了十几年,但目前许多现代编程语言的普遍特性还不完全具备,比如namespace/package
现如今JavaScript的广泛使用导致了许多框架级产物如雨后春笋般遍地开花,JavaScript库也亟需namespace/package这种特性支持
而当我们使用第三方库时,如果没有良好的namespace/package支持,我们也很容易陷入变量和函数重名的痛苦(比如jQuery和Prototype的“$”)
让我们先来看看简单的namespace/package实现:
// 伪造名字空间com.hideto var com; if (!com) com = {}; if (!com.hideto) com.hideto = {}; // 定义一个类com.hideto.MyClass com.hideto.MyClass = function (a) { this.a = a; }; com.hideto.MyClass.prototype.getA = function () { return this.a; }; //使用类com.hideto.MyClass var c = new com.hideto.MyClass("123456789"); alert(c.getA());
十分麻烦!
让我们创建一个辅助文件Module.js来帮助我们创建名字空间:
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( ) {}; } // 简化方法名 Module.c = Module.createNamespace; Module.i = Module.importSymbols;
我们这样使用Module辅助对象:
// 创建模块com.hideto Module.c("com.hideto"); // 定义一个方法com.hideto.print com.hideto.print = function(a) { document.write(a) }; // 定义一个类com.hideto.MyClass com.hideto.MyClass = function (a) { this.a = a; }; com.hideto.MyClass.prototype.getA = function () { return this.a; }; // 导入com.hideto模块 Module.i(com.hideto); // 调用print方法 print("123456789"); // 使用类MyClass var c = new MyClass("987654321"); alert(c.getA());
这样果然方便多了!
还有一些开源的JavaScript包管理工具,如jspkg
Mozilla的JavaScript 2.0 proposal和ECMAScript 4 Proposal都在JavaScript核心语法里添加了Namespaces和Packages功能
注:文中部分代码来自《JavaScript: The Definitive Guide》
发表评论
-
Ext源码解析:3, DomHelper.js
2008-07-15 16:45 2441from http://www.beyondrails.com ... -
Ext源码解析:2, DomQuery.js
2008-07-11 10:54 2642fromhttp://www.beyondrails.com/ ... -
Ext源码解析:1, Ext.js
2008-07-09 18:08 2947来自http://www.beyondrails.com/bl ... -
Extjs Introduction
2008-07-08 02:04 8833from http://hideto.beyondrails. ... -
模拟Ajax提交上传文件
2008-06-04 00:24 4231XMLHTTP不支持文件上传这种form提交,但是我们可以模拟 ... -
escape JavaScript
2008-03-27 16:55 2659单引号、双引号、<script></scri ... -
Multiple IE
2007-11-22 10:35 2562老问题,js和css对跨浏览器兼容问题 在一台电脑上共存IE3 ... -
编辑表单后离开本页面时做提示(jQuery版)
2007-11-15 15:21 5049添加如下JavaScript: $.fn.enable_c ... -
正确使用Prototype,节省额外的100K
2007-11-10 23:20 3093Part I: http://thinkweb2.com/pr ... -
十大Web应用漏洞清单,XSS排名第一
2007-10-22 12:36 3119owasp.org列出十大Web应用漏洞清单: 1, Cros ... -
IE下不能disabled掉select标签的option的解决方案
2007-10-11 17:48 9033原文:Select, Option, Disabled And ... -
Jester: JavaScript Client for REST
2007-09-04 13:51 2724Jester: JavaScriptian REST介绍了Je ... -
ASCB阅读笔记五、Arrays
2007-08-23 10:47 1819var array:Array = new Array() ... -
ASCB阅读笔记四、Numbers and Math
2007-08-15 12:08 2032显示最近的整数(四舍五入) Math.round(204.49 ... -
ASCB阅读笔记三、Runtime Environment
2007-08-10 23:34 25191,检测用户浏览器安装的Flash Player版本 http ... -
ASCB阅读笔记二、Custom Classes
2007-08-09 10:54 13761,ActionScript 3.0已经完全OO,所有AS代码 ... -
ASCB阅读笔记一、ActionScript Basics
2007-08-07 23:29 20521,使用trace来debug程序 package { ... -
method_missing in ActionScript 3/Flex
2007-08-07 18:05 2012method_missing in ActionScript ... -
Hilog 0.1 released.
2007-08-07 00:52 2091Hilog 0.1 release is a demo of ... -
在客户端保存状态
2007-08-05 18:13 3778Keeping State on the Client 在第 ...
相关推荐
为了使用"Solid-namespace"库,开发者需要按照README.md中的指示进行安装,通常是通过npm(Node Package Manager)进行,然后在项目中引入并使用。在实际项目中,这个库可以帮助简化RDF数据处理的代码,提升开发效率...
1. **命名空间和代码结构**:组织代码时,采用命名空间(Namespace)和包(Package)设计能有效避免命名冲突。例如,dojo、dojox和dijit是Dojo框架中的子项目。使用目录、文件和类来分隔代码,并创建良好的命名空间...
api.use('awei01:package-namespacer'); // still other code // include our files api.addFiles('foo.js'); // export the variable api.export('Foo'); }); 然后,在您的包定义代码( foo.js )中: Foo =...
2. 声明关键字:`catch`, `false`, `new`, `true`, `class`, `finally`, `null`, `try`, `const`, `for`, `package`, `typeof`, `continue`, `function`, `private`, `use`, `debugger`, `if`, `protected`, `var`, ...
#### 二、JavaScript自定义命名空间(namespace) 在JavaScript开发中,为了避免全局变量污染问题,通常会使用命名空间来组织代码。这不仅可以提高代码的可维护性,还可以避免不同脚本之间的命名冲突。 ##### 实现...
<package name="default" namespace="/" extends="struts-default"> <param name="maximumSize">1048576</param> <!-- 设置最大上传文件大小 --> <result name="success">/success.jsp </package> ``` ...
JavaScript中的命名空间(Namespace)是一种组织代码的方式,它有助于避免全局变量污染,提高代码的可维护性和可读性。在大型项目中,特别是在浏览器环境中,由于JavaScript的全局作用域特性,多个脚本可能会定义...
总结来说,`global-namespace-monitor`是一个JavaScript工具,它通过监控`window`对象防止全局作用域污染,支持MIT许可协议,可以帮助开发者维持代码质量,避免因全局变量引发的潜在问题。通过合理使用和集成,可以...
乔莫Qomo OpenProject是一个True OOP框架(具有名称空间,AOP,ajax,templet ...)和基于UI库的Web浏览器。 从企业项目中提取的项目。...namespace system # package/unit import # tiny ajax architecture # AOP Ar
The json module: JavaScript Object Notation The plistlib module: A Property-List Parser ctypes Enhancements Improved SSL Support Deprecations and Removals Build and C API Changes Port-Specific ...
javascript中本没有命名空间的概念,但是要体现面向对象的思想, 应当有命名空间,就像java中的package,.net中的namespace一样, 作用主要为了防止类名冲突,相同的类名只要属于不同的命名空间,便不会冲突。...
在JavaScript编程中,`namespace` 是一种常见的设计模式,用于组织和管理代码结构,使得代码更易读、更模块化。这里的"根据包名,在指定空间中创建对象"指的是通过包名来动态地构建嵌套的对象结构。让我们深入探讨这...
在Struts2 XML配置文件中,`package`标签是定义Action配置的主要元素,`namespace`属性则是用来区分不同的功能模块或者操作。例如,一个`namespace`为"/admin"的包可能包含了所有管理员相关的操作,而另一个`...
The :: Operator and the Global Namespace Qualifier 408 Custom Exceptions 410 Events 412 Expanding and Using CardLib 426 Summary 434 Exercises 435 Chapter 14: C# 3.0 Language ...
routerPlus = { enable : true , package : 'egg-router-plus' ,} ;特征加载app/router/**/*.js 这个插件会自动加载在app/router/**/*.js定义的app/router/**/*.js 。 注意:所有子路由器都会在app/router.js之前...
├── NAMESPACE ├── NEWS.md ├── R │ ├── pending.R │ └── {packagename}-package.R ├── README.md ├── man │ └── {packagename}.Rd └── tests ├── test-all.R └── test...
将使用编译为 JavaScript 的文件导入您的应用程序。 安装 ember install:addon ember-cli-scala 用法 app/scala/Robot.scala : package robot import scala . scalajs . js import js . annotation . JSExport @...
<package name="default" namespace="/" extends="struts-default"> </package> ``` 这段配置告诉Struts2,除了`.action`扩展名外,还接受`.json`扩展,并且有一个结果类型为`json`的Action,这样当客户端...
install-package Microsoft.AspNet.SignalR 在解决方案资源管理器中,展开脚本文件夹。请注意,SignalR的脚本库已添加到项目中。 脚本文件夹 在解决方案资源管理器中,右键单击该项目,选择添加| 新建文件夹,并...
因此,您不再需要多个模板助手,并且即使将它们写入javascript或模板文件,也可以使用相同的符号来获取Meteor状态值。 用例 假设您要显示有关连接状态的信息: 前 mytemplate.html : <span>{{show_status}} ...