todomvc
Version:
> Helping you select an MV\* framework
93 lines (80 loc) • 2.43 kB
JavaScript
/** @license MIT License (c) copyright original author or authors */
/**
* Licensed under the MIT License at:
* http://www.opensource.org/licenses/mit-license.php
*/
(function(define){ 'use strict';
define(function() {
var undef;
/**
* Creates an object by either invoking ctor as a function and returning the result,
* or by calling new ctor(). It uses a simple heuristic to try to guess which approach
* is the "right" one.
*
* @param ctor {Function} function or constructor to invoke
* @param args {Array} array of arguments to pass to ctor in either case
*
* @return The result of invoking ctor with args, with or without new, depending on
* the strategy selected.
*/
return function instantiate(ctor, args, forceConstructor) {
var begotten, ctorResult;
if (forceConstructor || isConstructor(ctor)) {
begotten = Object.create(ctor.prototype);
defineConstructorIfPossible(begotten, ctor);
ctorResult = ctor.apply(begotten, args);
if(ctorResult !== undef) {
begotten = ctorResult;
}
} else {
begotten = ctor.apply(undef, args);
}
return begotten === undef ? null : begotten;
};
/**
* Carefully sets the instance's constructor property to the supplied
* constructor, using Object.defineProperty if available. If it can't
* set the constructor in a safe way, it will do nothing.
*
* @param instance {Object} component instance
* @param ctor {Function} constructor
*/
function defineConstructorIfPossible(instance, ctor) {
try {
Object.defineProperty(instance, 'constructor', {
value: ctor,
enumerable: false
});
} catch(e) {
// If we can't define a constructor, oh well.
// This can happen if in envs where Object.defineProperty is not
// available, or when using cujojs/poly or other ES5 shims
}
}
/**
* Determines whether the supplied function should be invoked directly or
* should be invoked using new in order to create the object to be wired.
*
* @param func {Function} determine whether this should be called using new or not
*
* @returns {Boolean} true iff func should be invoked using new, false otherwise.
*/
function isConstructor(func) {
var is = false, p;
for (p in func.prototype) {
if (p !== undef) {
is = true;
break;
}
}
return is;
}
});
})(typeof define == 'function'
// AMD
? define
// CommonJS
: function(factory) {
module.exports = factory();
}
);