Skip to content

Instantly share code, notes, and snippets.

@amatiasq
Last active February 15, 2021 22:18
Show Gist options
  • Save amatiasq/5254098 to your computer and use it in GitHub Desktop.
Save amatiasq/5254098 to your computer and use it in GitHub Desktop.
A simple constructor extension function. Creates a constructor who prototypes "this" and adds the properties passed.
/*globals define, module */
//jshint camelcase: false, curly:false
(function(root) {
'use strict';
// __proto__ will be used if supported
//jshint -W103
function prototype_PROTO(parent, child, methods) {
methods.__proto__ = parent.prototype;
child.prototype = methods;
}
function prototype_ECMA5(parent, child, methods) {
child.prototype = Object.create(parent.prototype);
Object.keys(methods).forEach(function(name) {
Object.defineProperty(child, name, Object.getOwnPropertyDescriptor(methods, name));
});
}
function prototype_DEFAULT(parent, child, methods) {
function Intermediate() { }
Intermediate.prototype = parent.prototype;
child.prototype = new Intermediate();
for (var prop in methods)
if (methods.hasOwnProperty(prop))
child.prototype[prop] = methods[prop];
}
var prototype = {}.__proto__ ? prototype_PROTO : Object.create ? prototype_ECMA5 : prototype_DEFAULT;
function extend(config) {
config = config || {};
// No strict vilation, extend should be a method of a object
//jshint -W040
var parent = this;
var clazz = config.hasOwnProperty('constructor') ?
config.constructor :
function() { parent.apply(this, arguments); };
prototype(parent, clazz, config || {});
clazz.prototype.constructor = clazz;
clazz.extend = extend;
return clazz;
}
if (typeof define !== 'undefined' && define.amd)
define(function() { return extend });
else if (typeof module !== 'undefined')
module.exports = extend;
else
root.extend = extend;
})(this);
//
// Native constructor extension
//
var BasicType = extend.call(Object);
var MyOwnError = extend.call(Error, {
myOwnMethod: function() {
return 'Keep calm and debug --[' + this.message + ']--';
}
});
//
// Inheriting
//
var OtherError = MyOwnError.extend();
console.log(MyOwnError === OtherError);
// > false
var SubType = BasicType.extend({
constructor: function() {
BasicType.call(this);
console.log('constructing...');
},
a: 'hello world'
});
var sample = new SubType();
// > constructing...
console.log(sample.a);
// > hello world
console.log(sample instanceof SubType);
// > true
console.log(sample instanceof BasicType);
// > true
console.log(sample instanceof MyOwnError);
// > false
console.log(sample.constructor === SubType);
// > true
//
// ECMAScript5
//
// Usually other extend functions (like underscore) will invoke the getter when .extend() is invoked.
var TypeWithGetter = BasicType.extend({
get lol() {
console.log('Getting lol');
return 'trololo';
}
});
var otherSample = new TypeWithGetter();
console.log(otherSample.lol);
// > Getting lol
// > trololo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment