0

So I have this class definition:

class Field {
    constructor(canvas) {
        const CANVAS = document.querySelector(canvas);
        const CONTEXT = CANVAS.getContext("2d");

        return Object.assign(CONTEXT, Field.prototype); // *
    }

    prototypeMethodName() {
        return "something";
    }
}

console.log(new Field("canvas"));
<canvas></canvas>

The main idea here is that when I invoke new Field() I get not the instance of Field, but the object consisting of two other objects: CONTEXT and Field.prototype. The CONTEXT is the instance of the CanvasRenderingContext2D, and, basically, I just want to augument it with other methods (in this example it's just one method prototypeMethodName()).

But in this case I get a bare CONTEXT object that doesn't contain any of "my" properties.

I also noticed that the assign method doesn't work correctly only when I'm trying to merge a prototype of something to the tatget object. So the thing here is not about the CONTEXT object, but is about the prototype.

Why doesn't my code work? What would I do to make it work then?

smellyshovel
  • 176
  • 10

2 Answers2

0

I just want to augument it with other methods

Don't do that. Use composition instead.

But I get a bare CONTEXT object that doesn't contain any of "my" properties. I also noticed that the assign method doesn't work correctly only when I'm trying to merge a prototype of something to the target object.

Yes. The prototype objects of classes are not containing any enumerable methods, so Object.assign doesn't find them. Have a look at ES6 Iterate over class methods.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Allright. I got the part about enumerables. But I think you are wrong about extending native objects. The thing is I don't extend it globaly (on a global level). Instead, I just want a separate copy that is augumented with my own methods. I just wanna say that, I think, it would be bad of me if I would extend the `CanvasRenderingContext2D`'s prototype globaly, but I don't do that. – smellyshovel Dec 17 '17 at 12:48
  • Anyway, thank you for pointing me to enumerables. I'll try to find another way to satisfy my needle. – smellyshovel Dec 17 '17 at 12:49
  • @smellyshovel yes, extending local instances might be OK (if you control where these instances are used and where not) and is certainly better than extending a native prototype object, but you still risk name collisions with future extensions of the web platform. – Bergi Dec 17 '17 at 13:13
  • I see. Thank you! – smellyshovel Dec 18 '17 at 10:11
-1

try this

merge(context, field) {
    for(let prop in Field.prototype) {
        context.prototype[prop] = Field.prototype[prop];
    }
    return context;
}
mark
  • 44
  • 2
  • I don't think that it might work cause if I remember correctly `for in` only loops throgh enumerable props. And, how Bergi said, the properties of prototypes are not enumerable. – smellyshovel Dec 18 '17 at 10:12