Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about how to create classes in JavaScript

In the past when creating "classes" in JavaScript, I have done it like this:

function Dog(name){
    this.name=name;
    this.sound = function(){
        return "Wuf";
    };
}

However, I just saw someone do it like this instead:

var Dog = (function () {
    function Dog(name) {
        this.name = name;
    }
    Dog.prototype.sound = function () {
        return "Wuf";
    };
    return Dog;
})();

Can you do it both ways, or is the way I've done it wrong? In that case, why? And what exactly is the difference between the two in terms of what we end up with? In both cases we can create an object by saying:

var fido = new Dog("Fido");
fido.sound();

I hope someone will enlighten me.

like image 997
MBrown Avatar asked Mar 24 '15 13:03

MBrown


People also ask

What are the ways that you can create classes in JavaScript?

Class methods are created with the same syntax as object methods. Use the keyword class to create a class. Always add a constructor() method. Then add any number of methods.

Is it good practice to use classes in JavaScript?

In JavaScript, you don't! You can write any program you want without utilizing classes or the this keyword ever! Indeed, the class syntax is somewhat new to JavaScript, and object oriented code was written with functions beforehand. The class syntax is just syntactic sugar over that function-based approach to OOP.

Why are there no classes in JavaScript?

JavaScript didn't originally have classes. Classes were added with the introduction of ECMASCRIPT 6 (es6), a new and improved version of JavaScript (ECMASCRIPT 5 being the older version). A typical JavaScript class is an object with a default constructor method.

How are JavaScript classes different?

Classes. The most important difference between class- and prototype-based inheritance is that a class defines a type which can be instantiated at runtime, whereas a prototype is itself an object instance.


2 Answers

There are two important differences between your way and theirs.

  1. Wrapping in a self invoking function ((function() { ... })();)
  2. Using the .prototype property over this. for methods.

Wrapping things in a self invoking function, then assigning the result (as defined in the return statement to a variable is called the module pattern. It's a common pattern to ensure scope is more controlled.

Using Dog.prototype.sound = function() {} is preferable to this.sound = function(). The difference is that Dog.prototype.sound is defined once for all objects with the Dog constructor, and the this.sound = function() {} is defined again for each Dog object created.

The rule of thumb is: Things that are individual to an object (usually its properties) are to be defined on this, while things that are shared to all objects of the same type (usually functions) are to be defined on the prototype.

like image 67
Madara's Ghost Avatar answered Sep 22 '22 18:09

Madara's Ghost


With your code, you're creating a new function sound for every new Dog instance that's being created. Javascript's prototype avoids this by creating only a single function which all object instances share; basically classical inheritance.

In the second code you're showing that's just additionally wrapped in an IIFE, which doesn't do much in this case.

like image 40
deceze Avatar answered Sep 22 '22 18:09

deceze