Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active August 29, 2015 14:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barneycarroll/445279090cdb05945712 to your computer and use it in GitHub Desktop.
Save barneycarroll/445279090cdb05945712 to your computer and use it in GitHub Desktop.
ES6 classes in ES5.
var slice = Array.prototype.slice;
function Class( Super, Schema ){
if( arguments.length < 2 ){
Schema = Super;
Super = Object;
}
var constructor = Schema.constructor ? Super ? function SubClass(){
var args = slice.call( arguments );
return new ( Schema.construnctor.bind.apply( Schema.constructor, [ undefined ].concat( args.concat( Super ) ) ) )();
} : Schema.constructor : function Class(){};
var property;
for( property in Super.prototype ){
if( !( Schema.hasOwnProperty( property ) ) ){
constructor.prototype[ property ] = Super.prototype[ property ];
}
}
for( property in Schema ){
if( Schema.hasOwnProperty( property ) && property !== 'constructor' ){
if( Schema[ property ] instanceof Function && Super.prototype.hasOwnProperty( property ) ){
constructor.prototype[ property ] = function subMethod(){
var args = slice.call( args );
return Schema[ property ].apply( args.concat( Super.prototype[ property ].bind( this ) ) );
};
}
else {
constructor.prototype[ property ] = Schema[ property ];
}
}
}
return constructor;
}
@barneycarroll
Copy link
Author

// Dirt-simple
class Foo{}
// becomes
var Foo = Class();

// Constructors and prototypes
class Foo{
    constructor( name ){
        this.name = name;
    },
    greet(){
        return `Hiya, I'm ${name}`;
    }
}
// becomes
var Foo = Class( {
    constructor : function( name ){
        this.name = name;
    },
    greet : function(){
        return 'Hiya, I\'m ' + name;
    }
} );

// Subclassing, super references
class Bar extends Foo {
    constructor( name, surname ){
        super( name );

        this.surname = surname;
    },
    greet(){
        return `${super()} ${surname}`;
    }
}
// becomes
var Foo = Class( {
    constructor : function( name, surname, Super ){
        Super.call( this );

        this.name = name;
    },
    greet : function( super ){
        return super() + ' ' + surname;
    }
} );

@sloria
Copy link

sloria commented Mar 26, 2015

I've been happy with these tiny guys:

function defclass(prototype) {
    var constructor = prototype.hasOwnProperty('constructor') ? prototype.constructor : noop;
    constructor.prototype = prototype;
    return constructor;
}

function extend(cls, sub) {
    var prototype = Object.create(cls.prototype);
    for (var key in sub) { prototype[key] = sub[key]; }
    prototype.super = cls.prototype;
    return defclass(prototype);
}

// usage
var Foo = defclass( {
    constructor : function( name ){
        this.name = name;
    },
    greet : function(){
        return 'Hiya, I\'m ' + name;
    }
} );

var Bar = extend(Foo, {
    constructor : function( name, surname, Super ){
        this.super.call( this );

        this.name = name;
    },
    greet : function(){
        return this.super.greet.call(this) + ' ' + surname;
    }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment