zoukankan      html  css  js  c++  java
  • JavaScript 命名空间

    本文内容

    • 命名空间
    • 自定义命名空间 

    命名空间在面向对象编程语言中很常见,用来组织类。多年的工程实践表明,无论是面向对象还是其命名空间都很有效。但是,JavaScript 是基于原型的,本身并不支持面向对象,可我们很想把面向对象实践出来的结果应用到 JavaScript 中,以加强 JavaScript 代码的可维护性。而命名空间是不可缺少的一个环节,当然除此之外,还有用 JavaScript 模拟对象、继承等。

    在 JavaScript 编程中,很容易造成命名冲突,如果对局部变量不使用 var 关键字,则 JavaScript 认为是全局变量。试想,要是多人一起开发,更一步,每个人都开发自己的插件,命名冲突就是不可避免的,而最后若想修正这样的错误并不容易。

    命名空间


    只有一个全局作用域导致的常见错误是命名冲突。在 JavaScript中,这可以通过匿名包装器轻松解决。

    (function() {
        // 函数创建一个命名空间
     
        window.foo = function() {
            // 对外公开的函数,创建了闭包
        };
     
    })(); // 立即执行此匿名函数

    匿名函数被认为是表达式;因此为了可调用性,它们首先会被执行。

    ( // 小括号内的函数首先被执行
    function() {}
    ) // 并且返回函数对象
    () // 调用上面的执行结果,也就是函数对象

    有一些其他的调用函数表达式的方法,比如下面的两种方式语法不同,但是效果一模一样。

    // 另外两种方式
    +function(){}();
    (function(){}());

    带“+”的方式,第一次看见是在 ckeditor 中,当时有点惊讶。

    推荐使用匿名包装器(自执行的匿名函数)来创建命名空间。这样不仅可以防止命名冲突, 而且有利于程序的模块化。另外,使用全局变量被认为是不好的习惯。这样的代码倾向于产生错误和带来高的维护成本。

     

    自定义命名空间


    下面代码,实现自己命名空间机制如下:

    myNamespace = {
        // 全局对象仅仅存在 reg 函数, 参数为名称空间全路径, 如 myCustomer.control
        reg: function (ns) {
            var nsArray = ns.split('.');
            var sEval = "";
            var sNS = "";
            for (var i = 0; i < nsArray.length; i++) {
                if (i != 0) sNS += ".";
                sNS += nsArray[i];
                // 依次创建构造命名空间中的对象,
                // 如,若 myCustomer 不存在,则创建; 若 myCustomer.control 不存在,则创建……
                sEval += "if (typeof(" + sNS + ") == 'undefined') " + sNS + " = { };"
            }
            if (sEval != "") eval(sEval);
        }
    }
     
    // 注册自己的命名空间
    myNamespace.reg("myCustomer.control");
    myNamespace.reg("myCustomer.document");
     
    // 在 myCustomer.control 命名空间里面声明对象 myEditor
    myCustomer.control.myEditor = function (id, width, height) {
        this.id = id;
        this.width = width;
        this.height = height;
    }
     
    // 为对象 myEditor 添加一个公共方法 show
    myCustomer.control.myEditor.prototype.show = function () {
        alert("myEditor of control 's id is " + this.id + ", width is " + this.width + " and height is " + this.height);
    }
     
    // 演示如何使用类Person
    var p = new myCustomer.control.myEditor("txt1", 100, 100);
    p.show();
     
    if (typeof (myCustomer.document) != 'undefined') {
        alert('myCustomer.document exsit.');
    }
    else {
        alert('myCustomer.document nonexsit.');
    }

     

     

    下载 Demo

  • 相关阅读:
    Markdown编辑器:Typora
    Makefile的编写
    【转】Java基础——成员变量、局部变量和静态变量的区别
    【转】jsp 和 servlet的联系和区别
    【转】keySet和entrySet的区别
    10月25日下午PHP静态、抽象、接口
    10月25日上午PHP继承多态
    10月24日下午PHP封装
    10月24日上午PHP面向对象
    MYSQL存储过程、游标、触发器
  • 原文地址:https://www.cnblogs.com/liuning8023/p/3351244.html
Copyright © 2011-2022 走看看