Skip to content

Instantly share code, notes, and snippets.

@mrwest808
Last active August 29, 2015 14:23
Show Gist options
  • Save mrwest808/f203055bb6cad87e20fd to your computer and use it in GitHub Desktop.
Save mrwest808/f203055bb6cad87e20fd to your computer and use it in GitHub Desktop.
Object instantiation without `new` keyword
'use strict';
var inv = require('invariant'),
assign = require('lodash/object/assign'),
isObj = require('lodash/lang/isPlainObject'),
isFunc = require('lodash/lang/isFunction'),
toArray = require('lodash/lang/toArray');
/**
* Returns a function that creates a new object linked to the specified
* prototype object, optionally with a name reference to a constructor function.
*
* @param {Object} prototype
* @param {Function} constructor [Optional]
* @return {Function}
*/
var create = module.exports = function(prototype, constructor) {
prototype = prototype || {};
if(constructor) {
if(!isFunc(prototype[constructor]))
throw new ReferenceError('No `'+constructor+'` method');
}
/**
* Depending on whether a `constructor` parameter was passed to the wrapping
* function, this will:
*
* A) accept an object to use as the instance's own enumerable properties
* B) call the constructor method with the supplied parameters
*
* In both scenarios, a new object instance is returned.
*
* @return {Object}
*/
return function instantiate(properties) {
if(!constructor) {
properties = properties || {};
inv(isObj(properties), 'Initial `properties` should be a plain object');
return assign(Object.create(prototype), properties);
}
var obj = Object.create(prototype);
obj[constructor].apply(obj, toArray(arguments));
return obj;
};
};
'use strict';
/**
* Uncommented alternative version, where the `constructor` is an actual
* function instead of a name reference to a function on the supplied
* `prototype` object.
*
* Probably wouldn't provide any benefit, but would allow you to omit an
* explicit constructor function on your prototype object.
*/
var inv = require('invariant'),
assign = require('lodash/object/assign'),
isObj = require('lodash/lang/isPlainObject'),
isFunc = require('lodash/lang/isFunction'),
toArray = require('lodash/lang/toArray');
var create = module.exports = function(prototype, constructor) {
prototype = prototype || {};
if(constructor) {
if(!isFunc(constructor))
throw new TypeError('Invalid `constructor` function');
}
return function instantiate(properties) {
if(!constructor) {
properties = properties || {};
inv(isObj(properties), 'Initial `properties` should be a plain object');
return assign(Object.create(prototype), properties);
}
var obj = Object.create(prototype);
constructor.apply(obj, toArray(arguments));
return obj;
};
};
@Dodsaren
Copy link

Love it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment