原文:Namespacing in Javascript
说明:js语法结构松散,没有正式的命名空间结构或标准,所以管理命名空间的方法有很多,以下是其中常见的几种:
静态命名空间
1.直接指定
优点:稳妥。。。
缺点:写死了,属性Public
实现:
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会让这个对象的维护性好一些,但增加了不规范使用的风险
2.对象字面量表示法
优点:一次性声明对象的所有方法,比1看起来简洁一点,但没什么用
缺点:同上
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.模块化模式(Module Pattern,最常用)
优点:利用js的函数作用域和闭包特性实现私有属性,而且看起来很像java中的类
缺点:暂时没想到
实现:这里与原文有不同,我希望可以复用,就没有使用立即执行函数
var myApp = function() { ????var id= 0; ????return { ???????next: function() { ???????????return id++; ???????????}, ????????reset: function() { ???????????id = 0; ????????????} ???}; ?}var a = myApp()//undefineda.next()//0a.next()//1a.next()//2var b= myApp()//undefinedb.next()//0//这里a与b相互独立,表示可以直接复用myAppa.id//undefined//id属性只能通过返回对象中的方法访问或修改,因为返回对象里根本没有id属性,这是闭包的应用之一
动态命名空间
1.提供一表示命名空间的参数
优点:属性私有,比模块化好的一点是,模块化返回了一个对象,那么声明的对象一定就是这个返回的对象。而这种方式只会在作为参数的原来的对象上添加几个私有属性和方法
实现:
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 ?
还可以显式地指定作用域为全局作用域:(作为js库的提供者这么写可以让使用者自己决定某些特性应该是全局的还是局部的)
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 ?
2。使用this关键字实现命名空间代理
优点:使用原生js,语法简洁优美。由于apply和call自身语法特性,传参很方便
实现:
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
如果希望全局下有这么一些特性,直接运行就好了,不用apply和call
其他一些思考
应该避免使用嵌套的命名空间,因为这会使程序难以阅读——不论是对人还是对电脑。实际上这是一种怀旧的java式写法,有一长串的调用链
JS中命名空间的几种管理方式
原文地址:https://www.cnblogs.com/ilmare-notebook/p/9310840.html