Last active
August 29, 2015 14:08
-
-
Save insin/db5f79d7d97ee6200245 to your computer and use it in GitHub Desktop.
extend() which protects against new not being used in the default constructor it generates http://bl.ocks.org/insin/raw/db5f79d7d97ee6200245/
This file contains hidden or 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
// Modification of extend from Backbone.js 1.1.2 | |
// Helper function to correctly set up the prototype chain, for subclasses. | |
// Similar to `goog.inherits`, but uses a hash of prototype properties and | |
// class properties to be extended. | |
var extendSrsly = function() { | |
var hasOwn = Object.prototype.hasOwnProperty; | |
function extend(dest, src1, src2) { | |
for (var prop in src1) { | |
if (hasOwn.call(src1, prop)) { | |
dest[prop] = src1[prop] | |
} | |
} | |
if (src2) { | |
for (var prop in src2) { | |
if (hasOwn.call(src2, prop)) { | |
dest[prop] = src2[prop] | |
} | |
} | |
} | |
return dest | |
} | |
return function(protoProps, staticProps) { | |
var parent = this | |
var child | |
// The constructor function for the new subclass is either defined by you | |
// (the "constructor" property in your `extend` definition), or defaulted | |
// by us to simply call the parent's constructor (with protection against | |
// the user having forgotten to use the new keyword) | |
if (protoProps && hasOwn.call(protoProps, 'constructor')) { | |
child = protoProps.constructor | |
} else { | |
child = function(){ | |
if (!(this instanceof child)) { | |
return new_.apply(child, arguments) | |
} | |
return parent.apply(this, arguments) | |
} | |
} | |
// Add static properties to the constructor function, if supplied. | |
extend(child, parent, staticProps) | |
// Set the prototype chain to inherit from `parent`, without calling | |
// `parent`'s constructor function. | |
var Surrogate = function(){ this.constructor = child } | |
Surrogate.prototype = parent.prototype | |
child.prototype = new Surrogate | |
// Add prototype properties (instance properties) to the subclass, | |
// if supplied. | |
if (protoProps) { extend(child.prototype, protoProps) } | |
// Set a convenience property in case the parent's prototype is needed | |
// later. | |
child.__super__ = parent.prototype | |
return child | |
} | |
}() |
This file contains hidden or 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
<!DOCTYPE html> | |
<meta charset="UTF-8"> | |
<title>extendSrsly</title> | |
<script src="srsly.js"></script> | |
<script src="extendSrsly.js"></script> | |
<body> | |
<pre>var Person = User.extend({}) | |
var person = Person('Luigi', 'Mario')</pre> | |
<script> | |
function log(message) { | |
var pre = document.createElement('pre') | |
pre.appendChild(document.createTextNode(message)) | |
document.body.appendChild(pre) | |
} | |
function User(name, lastname) { | |
if (!(this instanceof User)) { | |
return new User(name, lastname) | |
} | |
this.name = name || 'Unknown' | |
this.lastname = lastname || 'Unknown' | |
}; | |
User.extend = extendSrsly | |
var Person = User.extend({}) | |
var person = Person('Luigi', 'Mario') | |
log('person instanceof Person // ' + (person instanceof Person) + '!') | |
log('person instanceof User // ' + (person instanceof User)) | |
log('JSON.stringify(person, null, 2) /* ' + JSON.stringify(person, null, 2) + ' */') | |
</script> | |
<a href="https://gist.github.com/insin/db5f79d7d97ee6200245"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> | |
</body> |
This file contains hidden or 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
function new_(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) { | |
switch (arguments.length) { | |
case 0: return new this | |
case 1: return new this(a) | |
case 2: return new this(a, b) | |
case 3: return new this(a, b, c) | |
case 4: return new this(a, b, c, d) | |
case 5: return new this(a, b, c, d, e) | |
case 6: return new this(a, b, c, d, e, f) | |
case 7: return new this(a, b, c, d, e, f, g) | |
case 8: return new this(a, b, c, d, e, f, g, h) | |
case 9: return new this(a, b, c, d, e, f, g, h, i) | |
case 10: return new this(a, b, c, d, e, f, g, h, i, j) | |
case 11: return new this(a, b, c, d, e, f, g, h, i, j, k) | |
case 12: return new this(a, b, c, d, e, f, g, h, i, j, k, l) | |
case 13: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m) | |
case 14: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n) | |
case 15: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) | |
case 16: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) | |
case 17: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) | |
case 18: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) | |
case 19: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) | |
case 20: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) | |
case 21: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) | |
case 22: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) | |
case 23: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) | |
case 24: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) | |
case 25: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) | |
case 26: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) | |
case 27: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A) | |
case 28: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B) | |
case 29: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C) | |
case 30: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D) | |
case 31: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E) | |
case 32: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F) | |
case 33: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G) | |
case 34: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H) | |
case 35: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I) | |
case 36: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J) | |
case 37: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K) | |
case 38: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L) | |
case 39: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M) | |
case 40: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N) | |
case 41: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) | |
case 42: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) | |
case 43: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) | |
case 44: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) | |
case 45: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) | |
case 46: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) | |
case 47: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) | |
case 48: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) | |
case 49: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W) | |
case 50: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X) | |
case 51: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y) | |
case 52: return new this(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) | |
default: throw new Error('SRSLY?????') | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment