bytebuffer.js icon indicating copy to clipboard operation
bytebuffer.js copied to clipboard

Subclassing is hard

Open pocesar opened this issue 9 years ago • 5 comments

Since all the 'static' functions (like concat, wrap, etc) use the ByteBuffer definition itself instead of "this", it's hard to subclass it. By using this.constructor and this (in static) instead of forcefully deriving from ByteBuffer, it can work. I can submit a patch, and I think it won't break anything, but will make it easier to add methods to the class without monkeypatching it

pocesar avatar Jan 18 '16 04:01 pocesar

export class BB extends ByteBuffer {

    static allocate( capacity?: number, littleEndian?: number, noAssert?: boolean ): BB {
        var c: BB = <any>super.allocate(capacity, littleEndian, noAssert);
        c.readBytes = this.prototype.readBytes;
        c.refresh = this.prototype.refresh;
        return c;
    }

    static wrap( buffer: ByteBuffer | Buffer | ArrayBuffer | Uint8Array | string | Array<number>, enc?: string | boolean, littleEndian?: boolean, noAssert?: boolean ): BB {
        var c: BB = <any>super.wrap(buffer, enc, littleEndian, noAssert);
        c.readBytes = this.prototype.readBytes;
        c.refresh = this.prototype.refresh;
        return c;
    }

    static concat( buffers: Array<ByteBuffer | Buffer |  ArrayBuffer | Uint8Array | string>, encoding?: string | boolean, litteEndian?: boolean, noAssert?: boolean ): BB {
        var c: BB = <any>super.concat(buffers, encoding, litteEndian, noAssert);
        c.readBytes = this.prototype.readBytes;
        c.refresh = this.prototype.refresh;
        return c;
    }

}

pocesar avatar Jan 23 '16 23:01 pocesar

So, what you are proposing basically is to change https://github.com/dcodeIO/bytebuffer.js/blob/master/src/methods/static/allocate.js#L12 and similar to:

return new this(capacity, littleEndian, noAssert);

Correct?

dcodeIO avatar Jan 23 '16 23:01 dcodeIO

Yup, exactly that, so it can be inherited from without those hacks. and when instance methods like clone, copy that returns a new ByteBuffer, should be new this.constructor()

pocesar avatar Jan 24 '16 00:01 pocesar

So, is this pattern safe to use across (not so modern) browsers?

dcodeIO avatar Jan 24 '16 00:01 dcodeIO

Yup, you can check in built-in classes, like [].constructor, ({}).constructor, (0).constructor,(function(){}).constructor and so on, it's from the first version of JS (1.1ish I think)

pocesar avatar Jan 24 '16 00:01 pocesar