Created
October 4, 2010 19:01
-
-
Save nw/610239 to your computer and use it in GitHub Desktop.
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
var assert = require('assert') | |
, subclass = function(type, proto){ | |
// make sure we are extending a global constructor | |
// accepted: [Boolean, Number, String, Array, Object, Function, RegExp, Date] | |
if(!global[type.name] || global[type.name].name != type.name) throw new Error(); | |
var constructor = proto.constructor, | |
keys = Object.keys(proto), | |
Obj = process.binding('evals').Script.runInNewContext('x = '+type.name), // eval ftw | |
obj = function(){ | |
var instance = new Obj(); | |
if(constructor) constructor.apply(instance, arguments); | |
return instance; | |
}; | |
obj.prototype.__proto__ = type.prototype; // passes instanceof 'type' | |
Obj.prototype.__proto__ = obj.prototype; // passes instanceof 'this' | |
for(var i=0,l=keys.length; i<l; i++){ | |
if(keys[i] != 'constructor') Obj.prototype[keys[i]] = proto[keys[i]]; | |
} | |
return obj; | |
} | |
, SpecialArray = subclass(Array, { | |
constructor: function(){ | |
Object.defineProperty(this, 'special', { | |
value: 'special', | |
enumerable: false | |
}); | |
}, | |
test: function(){} | |
}) | |
, arr = [] | |
, sa = new SpecialArray(); | |
// very strict, instance constructor === Array.constructor | |
assert.ok(Array.isArray(sa)); | |
// still passes instanceof Array tests | |
assert.ok(sa instanceof Array); | |
// still has unique identity | |
assert.ok(sa instanceof SpecialArray); | |
// should be extended | |
assert.ok(typeof sa.test == 'function'); | |
// this should not | |
assert.ok(typeof arr.test == 'undefined'); | |
// pass other hardcore type checks | |
assert.ok(Object.prototype.toString.call(sa) == '[object Array]'); | |
// make sure constructor works | |
assert.ok(sa.special == 'special'); | |
assert.ok(sa.propertyIsEnumerable('special') == false); | |
// make sure length property still works | |
assert.ok(sa.push(1,2,3) == 3); | |
assert.ok(sa.push(4,5) == 5); | |
assert.ok(sa.length == 5); | |
// check JSON.stringify() | |
assert.ok(JSON.stringify(sa) == '[1,2,3,4,5]'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment