菜单

Javascript的命名空间库,namespace命名空间使用说明

2019年8月5日 - 前端排行

github:
定义Namespace对象:
var Namespace
现行来具体看一下Namespace对象的定义,它是多个NamespaceDefinition对象。该指标是多个函数对象(NamespaceDefinition对象的构造函数,假设不给参数的话就默许生成二个main的命名空间),还应该有八特性格,Object,Definition,Proc。其值依次为NamespaceObjectFactory,NamespaceDefinition,createProcedure函数对象类。

谈起namespace命名空间笔者想多数敌人都精晓php有命名空间,asp.net有命名空间,那么我们要讲的是JavaScript的namespace命名空间哦,上边笔者来给各位介绍。

复制代码 代码如下:

写C恐怕JAVA习于旧贯的人写JavaScript时大概会开采JavaScript并不曾命名空间这一定义,当然若无接触过命名空间的程序员(比方写js,PHP,Python)也只怕对命名空间不关怀依旧不强调。那样的情况广泛存在,见过许四个人写JavaScript时直接就全局变量的写,如:

196 var createNamespace = function(fqn){
197 return new NamespaceDefinition(
198 NamespaceObjectFactory.create(fqn || ‘main’)
199 );
200 };
201 merge(createNamespace, {
202 ‘Object’ : NamespaceObjectFactory,
203 Definition: NamespaceDefinition,
204 Proc : createProcedure
205 });

 代码如下

NamespaceObjectFactory:根据fqn生成NamespaceObject对象。
NamespaceObjectFactory对象唯有三个create方法,参数正是命名空间的名字(Fully
Qualified
Name)。该方法有三个闭包情状,该条件里有贰个cache变量用于缓存全部更改的NamespaceObject对象。
三个NamespaceObject对象涵盖有两性子情,stash(记录当前namespace),fqn(namespace名字),proc(createProcedure对象)。方法包含:enqueue,call,valueof,merge,getStash,getExport

复制代码

复制代码 代码如下:

function a(){
 
}
 
function b(){
 
}

74 var NamespaceObject = function
_Private_Class_Of_NamespaceObject(fqn){
75 merge(this, {
76 stash: { CURRENT_NAMESPACE : fqn },
77 fqn : fqn,
78 proc : createProcedure()
79 });
80 };
81 merge(NamespaceObject.prototype, {
82 enqueue: function(context) {
83 this.proc.next(context);
84 },
85 call: function(state,callback) {
86 this.proc.call(state, callback);
87 },
88 valueOf: function() {
89 return “#NamespaceObject<” + this.fqn + “>”;
90 },
91 merge: function(obj) {
92 merge(this.stash,obj);
93 return this;
94 },
95 getStash: function() {
96 return this.stash;
97 },
98 getExport: function(importName) {
99 if (importName === ‘*’) return this.stash;
100
101 var importNames = importName.split(/,/),
102 retStash = {};
103 for(var i = 0,l=importNames.length;i<l;i++){
104 retStash[ importNames[i] ] = this.stash[ importNames[i] ];
105 }
106 return retStash;
107 }
108 });
109 var NamespaceObjectFactory = (function() {
110 var cache = {};
111 return {
112 create :function(fqn){
113 _assertValidFQN(fqn);
114 return (cache[fqn] || (cache[fqn] = new
NamespaceObject(fqn)));
115 }
116 };
117 })();

哪些是命名空间啊?语言应用的一种代码协会的花样
通过名称空间来分类,不一样差别的代码功能。无论项目大小,若是一初阶不严厉依据命名空间来编写程序,当您写到上万行JavaScript程序的时候,我深信你势必会后悔你的object恐怕function命名已经很混乱了。所以建议童鞋们一同先将在养成命名空间的习贯,比如您要支付四个等级次序,成效大概如下:

NamespaceDefinition:
该对象富含5个属性,namespaceObject,requires,useList,stash,defineCallback。并提供了相关的主意:use,_mergeStashWithNS,loadImport,define,getStash,valueOf,apply
该指标是namespace库的大旨,它提供了具有要求的艺术。
开头化的时候,在NamespaceObject的proc的steps队列里扩张四个函数对象,该函数将调用apply方法。

 

复制代码 代码如下:

那么你能够这么来定名:

119 var NamespaceDefinition = function
_Private_Class_Of_NamespaceDefinition(nsObj) {
120 merge(this, {
121 namespaceObject: nsObj,
122 requires : [],
123 useList : [],
124 stash : {},
125 defineCallback : undefined
126 });
127 var _self = this;
128 nsObj.enqueue(function($c){ _self.apply($c); });
129 };
130 merge(NamespaceDefinition.prototype, {
131 use: function(syntax){
132 this.useList.push(syntax);
133 var splitted = syntax.split(/\s+/);
134 var fqn = splitted[0];
135 var importName = splitted[1];
136 _assertValidFQN(fqn);
137 this.requires.push(function($c){
138 var context = this;
139 var require = NamespaceObjectFactory.create(fqn);
140 require.call(this,function(state){
141 context.loadImport(require,importName);
142 $c();
143 });
144 });
145 return this;
146 },
147 _mergeStashWithNS: function(nsObj){
148 var nsList = nsObj.fqn.split(/\./);
149 var current = this.getStash();
150
151 for(var i = 0,l=nsList.length;i<l-1;i++){
152 if( !current[nsList[i]] ) current[nsList[i]] = {};
153 current = current[nsList[i]];
154 }
155
156 var lastLeaf = nsList[nsList.length-1];
157 current[lastLeaf] = merge(current[lastLeaf] || {},
nsObj.getStash());
158 },
159 loadImport: function(nsObj,importName){
160 if( importName ){
161 merge( this.stash, nsObj.getExport(importName) );
162 }else{
163 this._mergeStashWithNS( nsObj );
164 }
165 },
166 define: function(callback){
167 var nsDef = this, nsObj = this.namespaceObject;
168 this.defineCallback = function($c) {
169 var ns = {
170 provide : function(obj){
171 nsObj.merge(obj);
172 $c();
173 }
174 };
175 merge(ns, nsDef.getStash());
176 merge(ns, nsObj.getStash());
177 callback(ns);
178 };
179 },
180 getStash: function(){
181 return this.stash;
182 },
183 valueOf: function(){
184 return “#NamespaceDefinition<“+this.namespaceObject+”> uses
:” + this.useList.join(‘,’);
185 },
186 apply: function(callback){
187 var nsDef = this;
188 createProcedure(nsDef.requires)
189 .next(nsDef.defineCallback)
190 .call(nsDef,function(){
191 callback( nsDef.getStash() );
192 });
193 }
194 });

 代码如下

createProcedure:该目的是三个函数对象,重返Procedure对象的next方法的结果。
Procedure:
Procedure对象有八个个性:state,steps,_status(默以为init)。提供一下两种艺术:next,isRunnig,enqueue,dequeue,call,_invoke。

复制代码

复制代码 代码如下:

// 配置
var config = {};
 
// 前台
config.front = {};
 
// 后台
config.admin = {};
 
// 后台数据
config.admin.data = {};
 
// 后台模块
config.admin.module = {};
 
// 后台颜色模块
config.admin.module.color = {};
 
// 后台图片模块
config.admin.module.images = {};
 
// 后台检索模块
config.admin.module.search = {};
 
 
 
// 给后台颜色模块加背景颜色改动功用
config.admin.module.color.changeBgColor = function(color) {
    document.body.style.background = color;
};
 
// 能够如此调用 
config.admin.module.color.changeBgColor(‘#F30’);

1 var Namespace = (function(){
2 /* utility */
3 var merge = function(target, source){ //
把source的具备本人性质copy到target中去,并赶回target对象 4 for(var p in
source)
5 if(source.hasOwnProperty( p )) target[p] = source[p];
6 return target;
7 };
8 var _assertValidFQN = function(fqn){ //
验证namespace名字的卓有成效,必须是小写英数字,下划线和点
9 if(!(/^[a-z0-9_.]+/).test(fqn)) throw(‘invalid namespace’);
10 };
11
12 var Procedure = function _Private_Class_Of_Proc(){
13 merge(this, {
14 state : {}, // 状态
15 steps : [], // 存款和储蓄状态的数组
16 _status: ‘init’
17 });
18 };
19 merge(Procedure.prototype, {
20 next: function(state){ //
倘使state有值,存入到steps队列队尾,然后回来this
21 if(state) this.enqueue(state);
22 return this;
23 },
24 isRunning: function(){ // 判别是还是不是为running状态
25 return (this._status === ‘running’);
26 },
27 enqueue: function(state){ //
这里实在是用数组steps来模拟队列,enqueue正是从队尾入队列
28 this.steps.push(state);
29 },
30 dequeue: function(){ // dequeue正是从对头骑行列
31 return this.steps.shift();
32 },
33 call: function(initialState,callback){ //
34 if( this.isRunning() ) throw(“do not run twice”);
35
36 this.state = initialState || {}; //
保存当前state(NamespaceDefinition对象)
37 this.enqueue(function($c){ // 函数入队列steps
38 $c(); // 实践传进来的函数
39 if(callback)callback(this); // 固然存在回调函数的,实践回调函数
40 });
41 this._status = ‘running’; // 设置情形为running
42 this._invoke(); // 调用_invoke
43 },
44 _invoke: function(){
45 var _self = this;
46 var step = _self.dequeue(); // 对象骑行列(FIFO)
47 if( !step ){
48 _self._status = ‘finished’; // 假诺队列为空,则设置情况为finished
49 return;
50 } // step是数组的图景下不走那条路线
51 if( step.call ) { //
假若该指标是函数对象的时候,则实践该call方法,并点名内部this为_self.state,回调函数里面继续调用_invoke
52 return step.call( _self.state,function _cont(state){
53 if( state ) _self.state = state;
54 _self._invoke();
55 });
56 }
57 var finishedProcess = 0;
58 if( step.length === 0 ) _self._invoke(); //
假如该数老板度为0,则调用_invoke
59 for(var i =0,l=step.length;i<l;i++){ //
针对数组里的享有指标(函数对象)调用各自的call方法,并点名各自函数的this为_self.state对象(nsDef对象)
60 step[i].call(_self.state,function _joinWait(){
61 finishedProcess++;
62 if( finishedProcess == l ){
63 _self._invoke();
64 }
65 });
66 }
67 }
68 });
69
70 var createProcedure = function(state) {
71 return new Procedure().next(state);
72 };
73
74 var NamespaceObject = function
_Private_Class_Of_NamespaceObject(fqn){
75 merge(this, {
76 stash: { CURRENT_NAMESPACE : fqn },
77 fqn : fqn,
78 proc : createProcedure()
79 });
80 };
81 merge(NamespaceObject.prototype, {
82 enqueue: function(context) {
83 this.proc.next(context);
84 },
85 call: function(state,callback) {
86 this.proc.call(state, callback);
87 },
88 valueOf: function() {
89 return “#NamespaceObject<” + this.fqn + “>”;
90 },
91 merge: function(obj) {
92 merge(this.stash,obj);
93 return this;
94 },
95 getStash: function() {
96 return this.stash;
97 },
98 getExport: function(importName) {
99 if (importName === ‘*’) return this.stash;
100
101 var importNames = importName.split(/,/),
102 retStash = {};
103 for(var i = 0,l=importNames.length;i<l;i++){
104 retStash[ importNames[i] ] = this.stash[ importNames[i] ];
105 }
106 return retStash;
107 }
108 });
109 var NamespaceObjectFactory = (function() {
110 var cache = {};
111 return {
112 create :function(fqn){
113 _assertValidFQN(fqn);
114 return (cache[fqn] || (cache[fqn] = new
NamespaceObject(fqn)));
115 }
116 };
117 })();
118
119 var NamespaceDefinition = function
_Private_Class_Of_NamespaceDefinition(nsObj) {
120 merge(this, {
121 namespaceObject: nsObj,
122 requires : [],
123 useList : [],
124 stash : {},
125 defineCallback : undefined
126 });
127 var _self = this;
128 nsObj.enqueue(function($c){ _self.apply($c); });
129 };
130 merge(NamespaceDefinition.prototype, {
131 use: function(syntax){ // 使用namespace
132 this.useList.push(syntax); // 该namespace字符串存入数组useList
133 var splitted = syntax.split(/\s+/); //
namespace和它的靶子使用空格分开
134 var fqn = splitted[0]; // 取得namespace
135 var importName = splitted[1]; // 获得namespace中的对象
136 _assertValidFQN(fqn);
137 this.requires.push(function($c){ // 放二个函数到requires数组中
138 var context = this;
139 var require = NamespaceObjectFactory.create(fqn); //
获取钦定的NamespaceObject对象,以前生成过得对象可以直接从缓存中赢得
140 require.call(this,function(state){ //
调用NamespaceObject对象的call方法
141 context.loadImport(require,importName);
142 $c();
143 });
144 });
145 return this;
146 },
147 _mergeStashWithNS: function(nsObj){
148 var nsList = nsObj.fqn.split(/\./);
149 var current = this.getStash();
150
151 for(var i = 0,l=nsList.length;i<l-1;i++){
152 if( !current[nsList[i]] ) current[nsList[i]] = {};
153 current = current[nsList[i]];
154 }
155
156 var lastLeaf = nsList[nsList.length-1];
157 current[lastLeaf] = merge(current[lastLeaf] || {},
nsObj.getStash());
158 },
159 loadImport: function(nsObj,importName){
160 if( importName ){
161 merge( this.stash, nsObj.getExport(importName) );
162 }else{
163 this._mergeStashWithNS( nsObj );
164 }
165 },
166 define: function(callback){
167 var nsDef = this, nsObj = this.namespaceObject;
168 this.defineCallback = function($c) { //
给defineCallback赋值,同时定义一下该回调函数的上下文,nsDef和nsObj三个对象。
169 var ns = {
170 provide : function(obj){
171 nsObj.merge(obj);
172 $c();
173 }
174 };
175 merge(ns, nsDef.getStash());
176 merge(ns, nsObj.getStash());
177 callback(ns);
178 };
179 },
180 getStash: function(){
181 return this.stash;
182 },
183 valueOf: function(){
184 return “#NamespaceDefinition<“+this.namespaceObject+”> uses
:” + this.useList.join(‘,’);
185 },
186 apply: function(callback){
187 var nsDef = this;
188 createProcedure(nsDef.requires)
189 .next(nsDef.defineCallback)
190 .call(nsDef,function(){
191 callback( nsDef.getStash() );
192 });
193 }
194 });
195
196 var createNamespace = function(fqn){
197 return new NamespaceDefinition(
198 NamespaceObjectFactory.create(fqn || ‘main’)
199 );
200 };
201 merge(createNamespace, {
202 ‘Object’ : NamespaceObjectFactory,
203 Definition: NamespaceDefinition,
204 Proc : createProcedure
205 });
206 return createNamespace;
207 })();

大家看看这段object在内部存款和储蓄器中的结构

日增定义Namespace补助的章程:
Namespace.use
Namespace.fromInternal
Namespace.GET
Namespace.fromExternal

 

复制代码 代码如下:

可是,以上注解命名空间的方法看起来不直观,我们来叁个比较直观的结构化命超格局:

1 Namespace.use = function(useSyntax){ return
Namespace().use(useSyntax); }
2 Namespace.fromInternal = Namespace.GET = (function(){
3 var get = (function(){
4 var createRequester = function() {
5 var xhr;
6 try { xhr = new XMLHttpRequest() } catch(e) {
7 try { xhr = new ActiveXObject(“Msxml2.XMLHTTP.6.0”) } catch(e) {
8 try { xhr = new ActiveXObject(“Msxml2.XMLHTTP.3.0”) } catch(e) {
9 try { xhr = new ActiveXObject(“Msxml2.XMLHTTP”) } catch(e) {
10 try { xhr = new ActiveXObject(“Microsoft.XMLHTTP”) } catch(e) {
11 throw new Error( “This browser does not support XMLHttpRequest.” )
12 }
13 }
14 }
15 }
16 }
17 return xhr;
18 };
19 var isSuccessStatus = function(status) {
20 return (status >= 200 && status < 300) ||
21 status == 304 ||
22 status == 1223 ||
23 (!status && (location.protocol == “file:” || location.protocol ==
“chrome:”) );
24 };
25
26 return function(url,callback){
27 var xhr = createRequester();
28 xhr.open(‘GET’,url,true);
29 xhr.onreadystatechange = function(){
30 if(xhr.readyState === 4){
31 if( isSuccessStatus( xhr.status || 0 )){
32 callback(true,xhr.responseText);
33 }else{
34 callback(false);
35 }
36 }
37 };
38 xhr.send(”)
39 };
40 })();
41
42 return function(url,isManualProvide){
43 return function(ns){
44 get(url,function(isSuccess,responseText){
45 if( isSuccess ){
46 if( isManualProvide )
47 return eval(responseText);
48 else
49 return ns.provide( eval( responseText ) );
50 }else{
51 var pub = {};
52 pub[url] = ‘loading error’;
53 ns.provide(pub);
54 }
55 });
56 };
57 };
58 })();
59
60 Namespace.fromExternal = (function(){
61 var callbacks = {};
62 var createScriptElement = function(url,callback){
63 var scriptElement = document.createElement(‘script’);
64
65 scriptElement.loaded = false;
66
67 scriptElement.onload = function(){
68 this.loaded = true;
69 callback();
70 };
71 scriptElement.onreadystatechange = function(){
72 if( !/^(loaded|complete)$/.test( this.readyState )) return;
73 if( this.loaded ) return;
74 scriptElement.loaded = true;
75 callback();
76 };
77 scriptElement.src = url;
78 document.body.appendChild( scriptElement );
79 return scriptElement.src;
80 };
81 var domSrc = function(url){
82 return function(ns){
83 var src = createScriptElement(url,function(){
84 var name = ns.CURRENT_NAMESPACE;
85 var cb = callbacks[name];
86 delete callbacks[name];
87 cb( ns );
88 });
89 }
90 };
91 domSrc.registerCallback = function(namespace,callback) {
92 callbacks[namespace] = callback;
93 };
94 return domSrc;
95 })();
96
97 try{ module.exports = Namespace; }catch(e){}

 代码如下

现实看三个事例:

复制代码

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图