[javascript] How to "properly" create a custom object in JavaScript?

A Pattern That Serves Me Well
var Klass = function Klass() {
    var thus = this;
    var somePublicVariable = x
      , somePublicVariable2 = x
      ;
    var somePrivateVariable = x
      , somePrivateVariable2 = x
      ;

    var privateMethod = (function p() {...}).bind(this);

    function publicMethod() {...}

    // export precepts
    this.var1 = somePublicVariable;
    this.method = publicMethod;

    return this;
};

First, you may change your preference of adding methods to the instance instead of the constructor's prototype object. I almost always declare methods inside of the constructor because I use Constructor Hijacking very often for purposes regarding Inheritance & Decorators.

Here's how I decide where which declarations are writ:

  • Never declare a method directly on the context object (this)
  • Let var declarations take precedence over function declarations
  • Let primitives take precedence over objects ({} and [])
  • Let public declarations take precedence over private declarations
  • Prefer Function.prototype.bind over thus, self, vm, etc
  • Avoid declaring a Class within another Class, unless:
    • It should be obvious that the two are inseparable
    • The Inner class implements The Command Pattern
    • The Inner class implements The Singleton Pattern
    • The Inner class implements The State Pattern
    • The Inner Class implements another Design Pattern that warrants this
  • Always return this from within the Lexical Scope of the Closure Space.

Here's why these help:

Constructor Hijacking
var Super = function Super() {
    ...
    this.inherited = true;
    ...
};
var Klass = function Klass() {
    ...
    // export precepts
    Super.apply(this);  // extends this with property `inherited`
    ...
};
Model Design
var Model = function Model(options) {
    var options = options || {};

    this.id = options.id || this.id || -1;
    this.string = options.string || this.string || "";
    // ...

    return this;
};
var model = new Model({...});
var updated = Model.call(model, { string: 'modified' });
(model === updated === true);  // > true
Design Patterns
var Singleton = new (function Singleton() {
    var INSTANCE = null;

    return function Klass() {
        ...
        // export precepts
        ...

        if (!INSTANCE) INSTANCE = this;
        return INSTANCE;
    };
})();
var a = new Singleton();
var b = new Singleton();
(a === b === true);  // > true

As you can see, I really have no need for thus since I prefer Function.prototype.bind (or .call or .apply) over thus. In our Singleton class, we don't even name it thus because INSTANCE conveys more information. For Model, we return this so that we can invoke the Constructor using .call to return the instance we passed into it. Redundantly, we assigned it to the variable updated, though it is useful in other scenarios.

Alongside, I prefer constructing object-literals using the new keyword over {brackets}:

Preferred
var klass = new (function Klass(Base) {
    ...
    // export precepts
    Base.apply(this);  //
    this.override = x;
    ...
})(Super);
Not Preferred
var klass = Super.apply({
    override: x
});

As you can see, the latter has no ability to override its Superclass's "override" property.

If I do add methods to the Class's prototype object, I prefer an object literal -- with or without using the new keyword:

Preferred
Klass.prototype = new Super();
// OR
Klass.prototype = new (function Base() {
    ...
    // export precepts
    Base.apply(this);
    ...
})(Super);
// OR
Klass.prototype = Super.apply({...});
// OR
Klass.prototype = {
    method: function m() {...}
};
Not Preferred
Klass.prototype.method = function m() {...};