/classtrophobic

Breaking JS Class Constrains

Primary LanguageHTMLMIT LicenseMIT

Classtrophobic build status Coverage Status

Zero Runtime, Babel Proof, Classes.

const Class = require('classtrophobic');

const List = Class({
  extends: Array,         // class extends Array {}
  constructor(...args) {  // super();
    this.super();
    this.push(...args);
  },
  push(...args) {         // super.push(...args);
    this.super.push(...args);
    return this;
  }
});

Don't Miss The Related Post

If you want to know more about this project use cases, and also why it was born in the first place, read the story in Medium.

Classtrophobic on ES5

Using some extra runtime, avoiding the usage of class and Proxy, Classtrophobic for ES5 works for all Mobile browsers, and IE11+ for Desktop.

Which Version For My Targets?

You can test live both classtrophobic and classtrophobic-es5. If the page turns out green, you're good to go!

The main difference is that ES5 version has a greedy runtime when it comes to super usage, while this original version uses real classes and delegate to Proxy access the super resolution, working only when a method is accessed and per single method, as opposite of runtime setup for all methods in the es5 case.

Luckily overrides are not the most frequent thing ever.

Ready for Refactory

Semantics used in native ES6 classes are equivalent in Classtrophobic.

// Native Class
class PushChainable extends Array {
  static size(arr) {
    return arr.length;
  }
  constructor(...args) {
    super().push(...args);
  }
  push(...args) {
    super.push(...args);
    return this;
  }
}

// Classtrophobic
const PushChainable = Class({
  extends: Array,
  static: {size:(arr) => arr.length},
  constructor(...args) {
    this.super().push(...args);
  },
  push(...args) {
    this.super.push(...args);
    return this;
  }
});

Feel free to compare transpiled output for both native and classtrophobic, considering each method that will use super, in the transpiled case, will be polluted with similar logic, inevitably increasing the final project size to deliver.

With Classtrophobic, the total amount of extra needed bytes is around 800 minified and gzipped. That's going to be the only extra code that will ever be needed to execute your classes, which is represented by 100 well indented LOC in total.

What Does Classtrophobic That Others Don't?

To start with, it uses native class, because there's more than just prototypal inheritance in ES2015 classes. As example, if you subclass an Array with good old JS, you'll lose your class as soon as you'll call a method.

function List() {}
Object.setPrototypeOf(List, Array);
Object.setPrototypeOf(List.prototype, Array.prototype);

(new List).slice() instanceof List; // ⚠️️ false

// even defining Symbol.species at runtime
Object.defineProperty(List, Symbol.species, {get:()=>List});

(new List).slice() instanceof List; // ⚠️️ still false

So while es-class and similar libraries can grant support for very old browsers, Classtrophobic needs no transpilation at its core and requires browsers natively compatible with classes.

In order to have a robust and fast super mechanism that perfectly simulate its native counter part, Classtrophobic also needs an engine that is compatible with Proxy.

Don't worry though, if you don't need super access, your code would run without needing a Proxy at all.

Compatibility

If your engine is compatible with ES2015 class, you can already use this tiny library. However, if your code needs super calls, be sure ES2015 Proxy is available too.

License

Copyright (C) 2017 by Andrea Giammarchi - @WebReflection

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.