Javascript define class

class, javascript

Solution

Note: The main answer below was written in 2012. See the end for additional notes regarding JavaScript's own `class` feature (ES2015+).

"Best" is an inherently subjective thing, but I'll try to point out some information about each and let you make up your own mind about "best."

Example 1

...gives you a handy scope (the anonymous function) where you can put truly private class-wide information (and utility functions) which only the `Class` functions have access to:

var Class = (function(){
    var trulyPrivateInformation = 42;

    function trulyPrivateUtilityFunction() {
        // ...
    }

    function Class() {
      this.test = 'test';
    }
    return Class;
})();

Example 1 is not "hoisted." It is processed as part of the step-by-step code.

The `Class` function will have a real name.

Example 2

...creates a function that has no name and assigns it to a variable that has a name. Modern browsers are pretty smart about it, but in theory at least, the function is anonymous, which impacts what information your tools can provide you. that (as of ES2015) has a name (`Class2`) except in obsolete environments like IE. It doesn't have the private class-wide scope Example 1 has.

Like Example 1, Example 2 is processed as part of the step-by-step code, not hoisted.

Example 3

...is just Example 1 without the private class-wide scope, but it's also "hoisted" — the `Class` function is defined before any step-by-step code is executed. That means this works:

var c = new Class();
console.log(c.test); // Logs 'test'

function Class() {
    this.test = 'test';
}

Note that even though `Class` is defined lower down, it's done before the code above runs. This isn't true of either Example 1 or Example 2.

As with Example 1 (but not 2), the `Class` function has a real name.

In 2015, JavaScript got its own `class` syntax. Here in 2019, it's natively supported by all modern browsers, and you can transpile with tools like Babel if you need to support IE. Here's how `class` would relate to the OP's question:

Example 1 with `class`

const Class = (() => {
    let trulyPrivateInformation = 42;

    function trulyPrivateUtilityFunction() {
        // ...
    }

    return class Class {
        constructor() {
            this.test = 'test';
        }
    }
})();

Processed in the step-by-step execution of code. Has truly private scope (within the anonymous scoping function) for truly private stuff. Has a proper name.

Example 2 with `class` (which is also Example 3 with `class`)

class Class2 {
    constructor() {
        this.test = 'test';
    }
}

let c2 = new Class2();
console.log(typeof Class2);
console.log(c2.test);

Processed in the step-by-step execution of code. Doesn't have the truly private scope Example 1 has (though private fields and methods are coming soon). Has a proper name.

Problem

What is the best way to define a class? I am aware of the fact that this is most of the times a choice of what you prefer to use, but what is the direct difference between these 3 examples? Example 1 ``` var Class = (function(){ function Class() { this.test = 'test' } return Class; })(); var c = new Class(); console.log(typeof Class); console.log(c.test); ``` Example 2 ``` var Class2 = function(){ this.test = 'test' }; var c2 = new Class2(); console.log(typeof Class2); console.log(c2.test); ``` Example 3 ``` function Class3(){ this.test = 'test' }; var c3 = new Class3(); console.log(typeof Class3); console.log(c3.test); ``` Sometimes I use it like this as well: var Class = (function(){ var Private = {}, Public = {}; ``` Private._doSomething = function() { // something } Public.doSomethingElse = function() { // something else } return Public; })(); ```

Original source