Should I embed constructors and prototypes in JavaScript?

The project I'm currently working on called an object type Chain

that itself creates the type of object Link

it uses. In previous projects, I nested an object constructor and prototype Link

inside the constructor for Chain

, however I started to wonder, this time, if this was the best way to do it, as I would actually appear to customize each Chain

with its own definition Link

each time.

For clarity, this was the original code I had:

var Chain = function() {
    var self = this;

    var Link = function(key) {
        this.prop = key;
    };
    Link.prototype.attach = function(args) {
        for (let value of args) {
            this[value.prop] = value.value;
        }
    };

    self.links = [];

}
Chain.prototype.add = function(key) {
    this.links.push(new Link(key));
}

      

Then I started wondering if I should just keep the constructor and prototype Link

wild like I have with Chain

(for the record, it's not entirely alone, it's actually contained within the object), or should I use the prototype Chain

to define Link

and store it there.

I have not been able to find much information on best practice in this situation, and while I strongly suspect that my first way of doing things is not the best / correct way; I'm not sure if my alternatives are either.

So my question is, what is the best practice / most efficient / sane way to do this?

+3


source to share


2 answers


In previous projects, I nested the object constructor and prototype Link

inside the constructor for Chain

, however I started to wonder, this time if that was the best way ...

Then I started wondering if it's worth it to just keep the constructor and prototype Link

wild like I have withChain

There is a third option, a single one Link

, which is closed to Chain

:

var Chain = (function() {
    function Link() {
        // ...
    }
    // Link.prototype stuff here

    function Chain() {
        // ...
    }
    // Chain.prototype stuff here

    return Chain;
})();

      



Chain

Is now public, Link

private, but only one exists Link

instead of creating a new one for each Chain

.

This works equally well with ES2015 + syntax class

:

const Chain = (function() {
    class Link {
        // ...
    }

    class Chain {
        // ...
    }

    return Chain;
})();

      

+5


source


I started to wonder, this time, if this is the best way to do it, since I would actually appear each one Chain

with its own definition Link

.

Yes, for this very reason it is not. You don't want to create thousands of classes Link

when creating thousands of circuits. Always place a class next to each other, never in another's constructor.

Sometimes an instance-specific helper function can be useful (for setting up a link specific to that particular chain), but you can do it as a factory method and still keep all references from all chains the same (base).

Should I just keep the Link constructor and prototype wild as I am with Chain

?



Yes, that's fine as far as the scope is. If wild isn't global, there is nothing wrong with that. If you like encapsulation, you can use ES6 modules to export only the "public" parts of this scope, or use an IIFE (as in @TJCrowder's answer).

Another common technique that keeps classes together if they belong together is to use the class as a namespace object:

var Chain = function() {
    this.links = [];
};// Chain.prototype

Chain.Link = function(key) {
    this.prop = key;
};// Chain.Link.prototype

      

The same works with ES6 class

es
.

+1


source







All Articles