Created
November 23, 2009 21:46
-
-
Save ELLIOTTCABLE/241405 to your computer and use it in GitHub Desktop.
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 () { | |
| if (typeof Object.prototype['beget'] !== 'function') { | |
| // This function creates and returns a new object, whose prototype is the | |
| // receiver. | |
| // | |
| // The value of the receiver’s `constructor` property is used as a | |
| // constructor function for the begat object. | |
| Object.prototype['beget'] = function (blueprint) { | |
| var originalPrototype = this['constructor']['prototype']; | |
| this['constructor']['prototype'] = this; | |
| // For some things (like `Object`), we can’t set the `prototype` | |
| // property without things blowing up horribly. That would create a | |
| // circular prototypal inheritance chain, which interpreters *really* | |
| // don’t like. Generally, they simply ignore the assignment. Thus, we’re | |
| // going to check that the assignment *actually happened*, and then if | |
| // not, use a new, beget-safe, constructor. | |
| if (this['constructor']['prototype'] !== this) { | |
| if (this.hasOwnProperty('constructor')) { | |
| var originalConstructor = this['constructor'] } | |
| else { var originalConstructor }; | |
| this['constructor'] = new(Function); | |
| var descendant = arguments.callee.apply(this, blueprint); | |
| if (typeof originalConstructor !== 'undefined') { | |
| this['constructor'] = originalConstructor } | |
| else { delete this['constructor'] }; | |
| return descendant; | |
| } | |
| var descendant = new(this['constructor'])(blueprint); | |
| descendant['blueprint'] = blueprint; | |
| this['constructor']['prototype'] = originalPrototype; | |
| return descendant; | |
| }}; | |
| return Object.prototype; | |
| })(); | |
| // -- -- -- ! -- -- -- // | |
| var sys = require('sys'); | |
| var assert = function (argument) { | |
| process.stdio.writeError('.'); | |
| if (!argument) { | |
| process.stdio.writeError('\n'); | |
| throw new(Error)("Assertion failed! [" + sys.inspect(argument) + "]"); | |
| }; | |
| }; | |
| // Some old values | |
| objectPrototype = Object.prototype; | |
| var anObject = new(Object); | |
| var tcejbOna = {}; | |
| assert( anObject !== tcejbOna ); | |
| assert( anObject.constructor === tcejbOna.constructor ); | |
| assert( anObject.constructor === Object ); | |
| assert( anObject['__proto__'] === tcejbOna['__proto__'] ); | |
| assert( anObject['__proto__'] === Object.prototype ); | |
| var descendant = anObject.beget(); | |
| assert( descendant !== anObject ); | |
| assert(!descendant.hasOwnProperty('constructor') ); | |
| assert( descendant.constructor === anObject.constructor ); | |
| assert( descendant['__proto__'] === anObject ); | |
| assert( typeof anObject['aProperty'] === 'undefined' ); | |
| anObject['aProperty'] = 'aValue'; | |
| assert( typeof anObject['aProperty'] !== 'undefined' ); | |
| assert( anObject['aProperty'] === 'aValue' ); | |
| assert( anObject.hasOwnProperty('aProperty') ); | |
| assert( typeof descendant['aProperty'] !== 'undefined' ); | |
| assert( descendant['aProperty'] === 'aValue' ); | |
| assert(!descendant.hasOwnProperty('aProperty') ); | |
| process.stdio.writeError('\n'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment