Dojo follows theAsynchronous Module Definition style which is self-speaking. 1.Logic in the define method; define method is the function in the dojo base which is located in dojo.js. The statements are as following which comply with AMD API
Dojo follows the Asynchronous Module Definition style which is self-speaking.
1.Logic in the define method;
define method is the function in the dojo base which is located in dojo.js. The statements are as following which comply with AMD API:
var def = function( mid, //(commonjs.moduleId, optional) list of modules to be loaded before running factory dependencies, //(array of commonjs.moduleId, optional) factory //(any) ){ /// // Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition. /// //note // CommonJS factory scan courtesy of http://requirejs.org var arity = arguments.length, defaultDeps = ["require", "exports", "module"], // the predominate signature... args = [0, mid, dependencies]; if(arity==1){ args = [0, (isFunction(mid) ? defaultDeps : []), mid]; }else if(arity==2 && isString(mid)){ args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies]; }else if(arity==3){ args = [mid, dependencies, factory]; } if(has("dojo-amd-factory-scan") && args[1]===defaultDeps){ args[2].toString() .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "") .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){ args[1].push(dep); }); } req.trace("loader-define", args.slice(0, 2)); var targetModule = args[0] && getModule(args[0]), module; if(targetModule && !waiting[targetModule.mid]){ // given a mid that hasn't been requested; therefore, defined through means other than injecting // consequent to a require() or define() application; examples include defining modules on-the-fly // due to some code path or including a module in a script element. In any case, // there is no callback waiting to finish processing and nothing to trigger the defQ and the // dependencies are never requested; therefore, do it here. injectDependencies(defineModule(targetModule, args[1], args[2])); }else if(!has("ie-event-behavior") || !has("host-browser") || injectingCachedModule){ // not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately // after script finishes being evaluated and the defQ can be run from that callback to detect the module id defQ.push(args); }else{ // IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1, // in-order exec of onLoad with script eval (since it's IE) and must manually detect here targetModule = targetModule || injectingModule; if(!targetModule){ for(mid in waiting){ module = modules[mid]; if(module && module.node && module.node.readyState === 'interactive'){ targetModule = module; break; } } if(has("dojo-combo-api") && !targetModule){ for(var i = 0; i<combosPending.length; i++){ targetModule = combosPending[i]; if(targetModule.node && targetModule.node.readyState === 'interactive'){ break; } targetModule= 0; } } } if(has("dojo-combo-api") && isArray(targetModule)){ injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2])); if(!targetModule.length){ combosPending.splice(i, 1); } }else if(targetModule){ consumePendingCacheInsert(targetModule); injectDependencies(defineModule(targetModule, args[1], args[2])); }else{ signal(error, makeError("ieDefineFailed", args[0])); } checkComplete(); } };2.Logic in the declare method
declare is defined in the dojo/_base/declare.js
function declare(className, superclass, props){ // crack parameters if(typeof className != "string"){ props = superclass; superclass = className; className = ""; } props = props || {}; var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass; // build a prototype if(opts.call(superclass) == "[object Array]"){ // C3 MRO bases = c3mro(superclass, className); t = bases[0]; mixins = bases.length - t; superclass = bases[mixins]; }else{ bases = [0]; if(superclass){ if(opts.call(superclass) == "[object Function]"){ t = superclass._meta; bases = bases.concat(t ? t.bases : superclass); }else{ err("base class is not a callable constructor.", className); } }else if(superclass !== null){ err("unknown base class. Did you use dojo.require to pull it in?", className); } } if(superclass){ for(i = mixins - 1;; --i){ proto = forceNew(superclass); if(!i){ // stop if nothing to add (the last base) break; } // mix in properties t = bases[i]; (t._meta ? mixOwn : mix)(proto, t.prototype); // chain in new constructor ctor = new Function; ctor.superclass = superclass; ctor.prototype = proto; superclass = proto.constructor = ctor; } }else{ proto = {}; } // add all properties declare.safeMixin(proto, props); // add constructor t = props.constructor; if(t !== op.constructor){ t.nom = cname; proto.constructor = t; } // collect chains and flags for(i = mixins - 1; i; --i){ // intentional assignment t = bases[i]._meta; if(t && t.chains){ chains = mix(chains || {}, t.chains); } } if(proto["-chains-"]){ chains = mix(chains || {}, proto["-chains-"]); } // build ctor t = !chains || !chains.hasOwnProperty(cname); bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) : (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t)); // add meta information to the constructor ctor._meta = {bases: bases, hidden: props, chains: chains, parents: parents, ctor: props.constructor}; ctor.superclass = superclass && superclass.prototype; ctor.extend = extend; ctor.createSubclass = createSubclass; ctor.prototype = proto; proto.constructor = ctor; // add "standard" methods to the prototype proto.getInherited = getInherited; proto.isInstanceOf = isInstanceOf; proto.inherited = inheritedImpl; proto.__inherited = inherited; // add name if specified if(className){ proto.declaredClass = className; lang.setObject(className, ctor); } // build chains and add them to the prototype if(chains){ for(name in chains){ if(proto[name] && typeof chains[name] == "string" && name != cname){ t = proto[name] = chain(name, bases, chains[name] === "after"); t.nom = name; } } } // chained methods do not return values // no need to chain "invisible" functions return ctor; // Function }