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

犀牛书笔记:(12)Modules and Namespaces

 
阅读更多

随着JS的发展,JS程序越写越长,就带来了命名冲突,

因此最重要的convention就是使用命名空间防止两个模块定义了同样名字的全局变量。

另一个重要的convention是引入模块初始化代码,这对浏览器中的JS尤其重要,因为在document加载完毕后操作某个指定document对象是很普遍的事情。

 

创建模块和命名空间

创建模块最重要的规则是,尽量避免定义全局变量,任何时候你定义了一个全局变量都是冒着可能被其他模块修改的危险。解决不使用全局变量的方法,就是使用自己定义的命名空间

 

 

//Create an empty object as our namespace
//This single global symbol will hold all of our other symbols
var Class = {};

//Define functions within the namespace
Class.define = function(data){ /* code goes here */}
Class.provides = function(o,c){ /* code goes here */}

 

 

一个模块不要在全局空间中定义超过一个变量

一旦模块在全局命名空间中加入了一个变量,它的文档必须清楚的说明这一点

一旦模块在全局命名空间中加入了一个变量,这个变量的名字和这个模块所在的文件名必须有清晰的关系

 

一般来讲,模块所在文件和全局变量的名字一致(这样,如果在都遵循这种命名规范的情况下,两个使用同一全局变量的模块是不能共存于同一目录下的),但如果在不同目录下连命名空间名都一样了(唯一的全局变量名一样),前面的一切设计就白费了,为了避免这种情况,将该命名空间所在的目录作为全局变量命名的一部分

 

/**
 * 将文件放置并命名为flanagan/Class.js
 *
 * 声明一个唯一的全局变量名为flanagan,并将命名空间设置为flanagan.Class,
 * 作为flanagan的一个属性。
 */
var flanagan;
if ( !flanagan) flanagan = {};  //如果这个变量没有用到
flanagan.Class = {}

flanagan.Class.define = function(data){....};
flanagan.Class.provides = function(o,c){....};

 

 注意到在上面的代码中,先使用了var操作符这是因为读取未定义的全局变量会抛出异常,而对于定义了而没初始化的全局变量,它的值只会是undefined这一现象仅仅对全局变量而言。

 

可以看出,这里flanagan是一个命名空间的命名空间,如果要更保险,可以使用JAVA的包命名方法

 

 

var com;
if (!com) com = {};
else if( typeof com != "object")
        throw new Error("com already exists and is not an object");

if( !com.davidflanagan) com.davidflanagan = {};
else if ( typeof com.davidflanagan != "object")
        throw new Error("com.davidflanagan already exists....");

if( com.davidflanagan.Class)
        throw new Error("com.davidflanagan.Class already exists");

com.davidflanagan.Class = {
     define: function(data) {...};
     provides: function(o,c){...};
};

 

 上面的例子是一个完整的严格的命名空间检查

 

测试模块是否加载:

 

var com;
if( !com || !com.davidflanagan || !com.davidflanagan.Class)
     throw new Error("com/davidflanagan/Class.js has not been loaded")

 

 某些地方还会加入一个版本属性,用来测试指定版本的模块是否加载

 

在指定命名空间建立一个类:

 

com.davidflanagan.Complex = com.davidflanagan.Class.define({
    name: "Complex",
    construct: function(x,y) {this.x = x; this.y = y;}
    methods: {
        add: function(c){
                  return new com.davidflanagan.Complex(this.x + c.x,
                                                                                  this.y + c.y);
         }
     },
});

 

建立多个类:

 

com.davidflanagan.shapes = {};

com.davidflanagan.shapes.Circle = define({});
com.davidflanagan.shapes.Rectangle = define({});
com.davidflanagan.shapes.Triangle = define({});

 

初始化模块代码:

这种代码只需要运行一次,因此使用匿名函数,并让它一旦定义就运行:

(function(){
   ...//code goes here
   ...//any variables are safely nested within the function
   ...//so no global symbols are created.
})();
 

为了得到唯一的命名空间,命名空间的名字往往冗长,在实际应用中,可以使用以下办法:

var define = com.davidflanagan.Class.define;

 

 

注意,引入的必须是函数,对象等类型,如果引入元类型,是没有意义的

另外一点是,引入简化名称,只是对于模块使用者而言,对于模块开发者,应该坚持使用全名

 

在模块内部,某个变量是内用还是外用,通常的区分方式重点还是在文档,另外是使用闭包

 

下面的例子创建了一个私有命名空间:

var com;
if(!com) com = {};
if( !com.davidflanagan) com.davidflanagan = {};
com.davidflanagan.Class = {};

(function(){
      function define(data){counter++;...};
      function provides(o,c){...};
      
      //counter变量将一直处于私有空间
      var counter = 0;
      function getCounter() {return counter; }
      
      var ns = com.davidflanagan.Class;
      ns.define = define;
      ns.provides = provides;
      ns.getCounter = getCounter;
})();
 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    [done]Cgroups and Namespaces.pdf

    [done]Cgroups and Namespaces.pdf

    Namespaces and cgroups

    management solutions: namespaces and cgroups. We will look at: ● Kernel Implementation details. ●what was added/changed in brief. ● User space interface. ● Some working examples. ● Usage of ...

    intermediate perl

    * Packages and namespaces * References and scoping, including regular expression references * Manipulating complex data structures * Object-oriented programming * Writing and using modules * ...

    Microsoft .NET Framework 3.5 Types and Namespaces

    Microsoft .NET Framework 3.5——Types and Namespaces Poster JAN08版 给广大学习.NET的同胞粉丝们 —————————————— 小闻子奉献

    Namespaces

    Namespaces

    15-namespaces-and-modules(命名空间和模块15).pdf

    15-namespaces-and-modules(命名空间和模块15).pdf

    sourceinsight4087

    Fix: Project > Add and Remove Project Files - fixed keyboard short cut in prompt to add top level sub-directories. Fix: Crash could happen when activating the Source Insight application window. Fix:...

    tcl tk reference guide

    12. System Interaction : : : : : : : : : : : : : : : : : : : : 10 13. File Input/Output : : : : : : : : : : : : : : : : : : : : : 11 14. Multiple Interpreters : : : : : : : : : : : : : : : : : : : 13 ...

    JavaScript权威指南第五版【新】(犀牛书)

    JavaScript权威指南,著名的犀牛书:) This Fifth Edition is completely revised and expanded to cover JavaScript as it is used in today's Web 2.0 applications. This book is both an example-driven ...

    Modern.PHP.New.Features.and.Good.Practices

    Title: Modern PHP: New Features and Good Practices Author: Josh Lockhart ...Chapter 12. HHVM and Hack Chapter 13. Community Appendix A. Installing PHP Appendix B. Local Development Environments

    Intermediate.Perl

    * Packages and namespaces * References and scoping * Manipulating complex data structures * Object-oriented programming * Writing and using modules * Testing Perl code * Contributing to ...

    Premier.Press.C++.Programming.for.the.Absolute.Beginner.2001.chm

    Chapter 12: Programming with Windows Chapter 13: Using DirectX Chapter 14: Creating the Pirate Adventure Apppendix A: Answers to Chapter Challenges Appendix B: Using the Octal, Hexadecimal, Binary, ...

    web-namespaces:Web名称空间地图

    该软件包仅适用于ESM:需要使用Node 12+才能使用它,并且必须将其import而不是require d。 : npm install web-namespaces 用 import { webNamespaces } from 'web-namespaces' console . log ( webNamespaces ) ...

    IOS 10 Programming Fundamentals with Swift: Swift, Xcode, and Cocoa Basic

    • Explore Swift s object-oriented concepts: variables and functions, scopes and namespaces, object types and instances • Become familiar with built-in Swift types such as numbers, strings, ranges, ...

    CSharp - Module 11_Aggregation Namespaces and Advanced Scope

    CSharp - Module 11_Aggregation Namespaces and Advanced Scope

    Programming with C++

    Chapter 12: Classes and Objects-2 291 Chapter 13: Operator Overloading 322 Chapter 14: Inheritance 339 Chapter 15: Virtual Functions and Polymorphism 369 Chapter 16: Templates 396 Chapter 17: C++ ...

    acpi控制笔记本风扇转速

    12 September 2006. Summary of changes for version 20060912: 1) ACPI CA Core Subsystem: Enhanced the implementation of the "serialized mode" of the interpreter (enabled via the AcpiGbl_...

    Pro TypeScript, 2nd Edition

    Coverage of major changes to modules, namespaces, and module loading New guidance on how to use inference to reduce the effort of using TypeScript Recommendations on compiler options A wide range of ...

    Ruby Cookbook

    Beginners and advanced Rubyists alike will learn how to program with: Strings and numbers Arrays and hashes Classes, modules, and namespaces Reflection and metaprogramming XML and ...

    Python库 | class_namespaces-0.5.6-py3-none-any.whl

    python库。 资源全名:class_namespaces-0.5.6-py3-none-any.whl

Global site tag (gtag.js) - Google Analytics