Js中的命名空间(namespace)

访客4年前黑客文章1165

全局变量应该由有系统局限相关性的工具们保留,而且它们的命名应该制止模糊并只管削减命名冲突的风险。在实践中,这意味着你应该制止建立全局工具,除非它们是绝对必须的。 不外,恩,这些你早都知道了……

以是你对此是怎么做的?传统方式告诉我们,更好的消除全局计谋是建立少数作为潜在模块和子系统的现实命名空间的全局工具。我将探索几种有关命名空间的方式,并以我基于 James Edwards最近的一篇文章获得的一个优雅、平安和天真的解决方案竣事。


静态命名空间

我我用静态命名空间作为那些命名空间标签现实上硬编码的解决方案的涵盖性术语。是的,你可以将一个命名空间重新分配给另一个,不外新的命名空间将会引用和旧的那一个同样的工具。

1.通过直接分配

最基础的方式。这样异常冗长,而且若是你还想重命名这些命名空间,你就有得活儿干了。不外它是平安和清晰明晰的。

var myApp = {}
myApp.id = 0;
myApp.next = function() {    return myApp.id++;  
}
myApp.reset = function() {
    myApp.id = 0;   
}window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
); //0, 1, undefined, 0

你也可以通过使用this引用兄弟属性来使未来的维护更轻松一些,不外这有一点冒险由于没有什么能阻止你的那些命名空间里的方式被重新分配。

var myApp = {}
myApp.id = 0;
myApp.next = function() {    return this.id++;   
}
myApp.reset = function() {    this.id = 0;    
}
myApp.next(); //0myApp.next(); //1var getNextId = myApp.next;
getNextId(); //NaN whoops!


2.使用工具字面量

现在我们只需要引用命名空间名一次,因此之后改变名字更简朴了一些(假设你还没频频引用这个命名空间)。仍有一个危险是this的值可能会抛出一个『惊喜』 – 不外假设在一个工具字面结构里界说的工具不会被重新分配相对平安一点。

var myApp = {
    id: 0,
    next: function() {        return this.id++;   
    },
    reset: function() {        this.id = 0;    
    }
}window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0


3.模块模式

我发现自己最近用模块模式更多。逻辑被一个方式包装从全局域隔离开了(通常是自挪用的),它返回一个代表这个模块公然接口的工具。通过立刻挪用这个方式并分配效果给一个命名空间变量,我们就锁住了这个命名变量中模块的 API。此外,任何没有包罗在返回值中的变量将永远保持私有,只对引用他们的公然方式可见。

var myApp = (function() {    var id= 0;    return {
        next: function() {            return id++;    
        },
        reset: function() {
            id = 0;     
        }
    };  
})();   
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0

如上工具字面量例子,命名空间名字可以容易替换,不外另有分外优势:工具字面量是四班的 – 它全是关于属性分配,没有支持逻辑的空间。此外,所有属性必须被初始化,而且属性值无法容易跨工具引用(因此,好比,内部闭包就不可能使用了)。模块模式没有任何上述约束,而且给我们分外的隐私福利。


动态命名空间

我们也可以将这一节称为命名空间注入。命名空间由一个直接引用方式包装内部的署理代表 – 这意味着我们不再需要打包分配给命名空间的返回值。这让命名空间界说变得更天真而且让拥有多个存在于自力命名空间中(或者甚至在全局上下文中)的模块的自力实例。动态命名空间支持模块模式的所有特征并附加直观和可读性强的优势。


4.提供命名空间参数

在这里我们只是将命名空间作为参数传给自挪用方式。变量id是私有的,由于他并没有被分配给context。

var myApp = {};
(function(context) { 
    var id = 0;
    context.next = function() {        return id++;    
    };
    context.reset = function() {
        id = 0;     
    }
})(myApp);  
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0

我们甚至可以把context设置给全局工具(通过一个字的改变!)。这是库主们的伟大财富 – 他们可以将他们的特征包装在一个自挪用函数中,然后让用户来决议它们是不是全局的(John Resig 在他写 JQuery 时就是一个这个理论的早期接纳者)。

var myApp = {};
(function(context) { 
    var id = 0;
    context.next = function() {        return id++;    
    };
    context.reset = function() {
        id = 0;     
    }
})(this);   
window.console && console.log(
    next(),
    next(),
    reset(),
    next()
) //0, 1, undefined, 0


5.用this作为命名空间署理

James Edwads 最近公布的一篇文章激起了我的兴趣。《My Favorite JavaScript Design Patter》
 显然被许多评论者误解了,他们以为他可能也是借助于模块模式。这篇文章宣传了多种手艺(可能导致了读者的疑惑),但是在它的焦点部门是一点我已经修改并呈现为一个命名空间工具的很天才的器械。

这个模式的美就在于它仅仅是根据这个语言被设计的方式使用 – 不多不少、不投契也不取巧。此外由于命名空间是通过this关键字(它在给定的执行上下文中是稳固的)注入的,它不可能被意外修改。

var myApp = {};
(function() {    var id = 0;    this.next = function() {        return id++;    
    };    this.reset = function() {
        id = 0;     
    }
}).apply(myApp);    

window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
); //0, 1, undefined, 0

更棒的是,apply(以及call) API 提供了与上下文和参数自然的隔离 – 因此给模块建立者通报附加参数异常清洁。下面的例子表明晰这一点,而且展示了如何自力于多个命名空间来运行模块。

var subsys1 = {}, subsys2 = {};var nextIdMod = function(startId) {    var id = startId || 0;    this.next = function() {        return id++;    
    };    this.reset = function() {
        id = 0;     
    }
};
nextIdMod.call(subsys1);    
nextIdMod.call(subsys2,1000);   
window.console && console.log(
    subsys1.next(),
    subsys1.next(),
    subsys2.next(),
    subsys1.reset(),
    subsys2.next(),
    subsys1.next()
) //0, 1, 1000, undefined, 1001, 0

固然若是我们若是我们需要一个全局 id 生成器,异常简朴……

nextIdMod();    
window.console && console.log(
    next(),
    next(),
    reset(),
    next()
) //0, 1, undefined, 0

这个我们作为例子使用的 id 生成器工具并没有表现出这个模式的所有潜力。通过包裹一整个库和使用this关键字作为命名空间的替身,我们使得用户在任何他们选择的上下文中运行这个库很轻松(包罗全局上下文)。

//library codevar protoQueryMooJo = function() {  
    //everything}//user codevar thirdParty = {};
protoQueryMooJo.apply(thirdParty);


其他的思量

我希望制止命名空间嵌套。它们很难追踪(对人和电脑都是)而且它们会让你的代码由于一些杂乱无章的器械变得许多。如 Peter Michaux 指出的,深度嵌套的命名空间可能是那些视图重新建立他们熟悉和热爱的长包链的老派 Java 开发者的遗产。

通过 .js 文件来牢固一个单独的命名空间也是可以的(虽然只能通过命名空间注入或者直接分配每一个变量),不外你应该对依赖郑重些。此外将命名空间绑定到文件上可以辅助读者更容易弄清整个代码。

由于 JavaScript 并没有正式的命名空间结构,以是有许多自然形成的方式。这个观察只详细说明晰其中的一部门,可能有更好的手艺我没有发现。我很愿意知道它们。

译文:@雷森图喵喜客 
链接:http://chengkang.me/2016/06/21/Namespacing%20in%20JavaScript/



思源资源网:分类流动

1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入

相关文章

qq技术交流,找黑客盗微信号骗局,找黑客找回密码

拜访一下看看有没有解析。 在道有道的官网上,介绍了其广告SDK的展现办法包含插屏广告、Banner广告和运用引荐广告。 -l list available modules意图地IP地址和域名在传输的...

美国允许新冠阳性医护工作

伴随着美国大选的落幕,美国的新冠疫情再次受到外界关注,根据美国媒体报道,受新冠肺炎疫情影响严重的北达科他州因为严重的医务工作者短缺问题竟然允许新冠阳性医护工作,光是从这一个州的情况就能看出美国的疫情已...

如何看待穷游 穷游和富游有什么区别

如何看待穷游 穷游和富游有什么区别

自助游本来是一件反映自身工作能力和心态的事儿,可是如今很多人歪曲了在其中的含意,有关自助游,有些人了解,有些人不赞同,而针对自助游和富游,有时候相互都不看不惯,那麼,怎样看待自助游?自助游和富游有什么...

怎么让蜘蛛天天来你的站

百度最近的算法让很多优化的朋友郁闷,因为很多网站出现百度不收录,快照不更新的现象。发现最近百度的很多算法做了调整,可能大部分是针对那些优化过度,采集过度的网站。那么,如何保持让百度及时收录你的文章呢?...

中级被通缉8年黑客(美国通缉4名中国黑客)

中级被通缉8年黑客(美国通缉4名中国黑客)

本文导读目录: 1、最厉害的黑客是? 2、凯文.米特尼克有什么事迹? 3、历史上最著名的几次黑客事件 4、黑客分为哪几个等级 5、著名的黑客事件都有哪些 6、最厉害的黑客是谁?...

城堡争霸黑客怎么刷钻石(腾讯城堡争霸bug刷宝石)

城堡争霸黑客怎么刷钻石(腾讯城堡争霸bug刷宝石)

本文导读目录: 1、城堡争霸怎么刷荣誉 刷荣誉攻略教程 2、目前城堡争霸到现在总共出现了多少种漏洞分别为那几种 3、城堡争霸怎么刷好天赋 4、地牢求生刷钻石怎么刷 5、城堡争霸无限宝石...