Define and declare method in Dojo

前端之家收集整理的这篇文章主要介绍了Define and declare method in Dojo前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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:

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[2]));
				if(!targetModule.length){
					combosPending.splice(i,1);
				}
			}else if(targetModule){
				consumePendingCacheInsert(targetModule);
				injectDependencies(defineModule(targetModule,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,chains[name] === "after");
					t.nom = name;
				}
			}
		}
		// chained methods do not return values
		// no need to chain "invisible" functions

		return ctor;	// Function
	}

猜你在找的Dojo相关文章