Skip to content
This repository
Browse code

Add a class_compat layer for easy access to traditional classes.

  • Loading branch information...
commit 24a4ae5364db6f4bc576154c609ca78dd4fc971c 1 parent e23f7ad
Tim Caswell authored August 19, 2010
4  lib/class.js
@@ -4,6 +4,10 @@ var Class = module.exports = Object.create(Object.prototype, {
4 4
   // Implement extend for easy prototypal inheritance
5 5
   extend: {value: function extend(obj) {
6 6
     if (obj === undefined) return Object.create(this);
  7
+    // Hook back so the constructor function still works like classical if needed
  8
+    if (typeof obj.constructor === 'function') {
  9
+      Object.defineProperty(obj.constructor, "prototype", {value: obj});
  10
+    }
7 11
     obj.__proto__ = this;
8 12
     Object.freeze(obj); // Lock the prototype to enforce no changes
9 13
     return obj;
29  lib/class_compat.js
... ...
@@ -0,0 +1,29 @@
  1
+var Class = require('./class');
  2
+
  3
+// This global modifier allows you to treat constructor based classes as if
  4
+// they were prototype based.
  5
+
  6
+// Define an extend method for constructor functions that works like prototype extends.
  7
+Object.defineProperty(Function.prototype, "extend", {value: function extend(obj) {
  8
+  // Clone the functions's prototype
  9
+  var props = {}, proto = this.prototype;
  10
+  Object.getOwnPropertyNames(proto).forEach(function (key) {
  11
+    props[key] = Object.getOwnPropertyDescriptor(proto, key);
  12
+  });
  13
+  
  14
+  // Put the constructor on a prop too
  15
+  props.constructor = {value: this};
  16
+  
  17
+  // Make obj's parent be an Classy version of props
  18
+  if (obj === undefined) return Object.create(Class, props);
  19
+  obj.__proto__ = Object.create(Class, props);
  20
+  Object.freeze(obj);
  21
+  return obj;
  22
+}});
  23
+
  24
+// This is the "new" keyword implemented in pure ES5
  25
+Object.defineProperty(Function.prototype, "new", {value: function () {
  26
+  var obj = Object.create(this.prototype, {constructor: this});
  27
+  var result = this.apply(obj, arguments);
  28
+  return result === undefined ? obj : result;
  29
+}});

1 note on commit 24a4ae5

Herbert Vojčík

I think this is not needed at all, but if you need it, I'd do it other way round - not copy the function's prototype and connect it to Class framework, but Objct.create() from the original function's prototype and extend it with Class framework stuff. It's much more safe and dynamic (reacts to changes made in original prototype in the run time).

But, personally, I do not see any need for any "Class" framework and old-school splitting the world between classes with behaviour and instances with state. Javascript is very powerful with its prototypal model, so use it as it was intended (only helper I would use are ones who stramline the clumsy (Subclass.prototype = Object.create(Superclass.prototype)), eventually ones who fill the prototype with content, so one does not need to write LongClassName.prototype.foo = function () {.... But as I said, that's my personal feeling.

Please sign in to comment.
Something went wrong with that request. Please try again.