Last active
February 15, 2021 22:18
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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