0

I've seen Javscript classes created all of these different ways:


function Thing() {

   method1: function() {

   },
   method2: function() {

   }   
}

Method 1


var thing = {

   method1: function() {

   },
   method2: function() {

   }   
};

Method 2


function Thing() {

}

Thing.prototype.method1 = function() {

}

Thing.prototype.method2 = function() {

}

Method 3


var thing = (function(){
   var b={};

   b.method1 = function(){

   };

   b.method2 = function class2(){

   };

   return b;
}());

Method 4


Do these different methods class of declaration have names, and what are they? Also have I missed any methods?

leeand00
  • 25,510
  • 39
  • 140
  • 297
  • 11
    Some of them yes. For example Method 1 is called "Syntax error". Method 2 - simple Object literal. Method 3 - usual "Prototypical pattern". Method 4 - module pattern basically. – dfsq Aug 05 '15 at 15:57
  • 3
    Mind your terminology - JavaScript is not Java. There's only one definitive way of creating 'classes' in JavaScript, and that's the ES6 `class` keyword, which is syntactical sugar. JavaScript remains a prototypical language. _It's objects all the way down._ – Oka Aug 05 '15 at 16:04
  • You might want to check my answer to this similar question: http://stackoverflow.com/questions/31832784/understanding-public-private-instance-variables/31834214#31834214 – Domino Aug 05 '15 at 16:10

2 Answers2

3

First, let's look at things you asked about which are not actually methods to make classes.

If you only need one object with methods, but no class, you can create an object literal.

var myObject = {
  varname: value,
  varname: value,
  methodname: function() {
     // do something
  },
  methodname: function() {
     // do something
  }
};

This is rarely useful, but it creates a single instance with its own variables, some of which are functions. Note that in JS, there is no difference between a property and a method. A method is just a property of type function.

Variables created inside a function with the var keyword are only available inside the function. People who make libraries often wrap their whole code in a closure in the form of a self-executing function, so that any temporary variables no longer exist at the end of the code:

(function(){
  // code here
}());

Now to make a class in JS, you only need to create a constructor function. You can store properties in the created instance with the this keyword.

function MyClass(param) {
  this.value = param;
}

var instance = new MyClass("example");

A function is a block of code stored in an object. You can store functions inside variables like anything else, so you can also store functions inside objects.

function MyClass() {
  this.myMethod = function() {
    alert("hi");
  };
}

But since all instances of your class will need to run the same code, it isn't efficient to create the function inside the constructor. That will make a new copy of the function for each instance you create. So instead of doing this, we store the function in the prototype of the object.

Whenever you type say, instance.someproperty, the JS engine looks at instance to see if it has a property called someproperty. If it doesn't, it tries to look at instance's prototype to see if it has a property of that name. And if it doesn't, it tries to look at that prototype's prototype... and so on, until it reaches the top of the chain.

So if you store the function in MyClass.prototype.myMethod, you will be able to call it with instance.myMethod and there will only be one copy of the function shared by all instances.

function MyClass(param) {
  this.value = param;
}

MyClass.prototype.myMethod = function() {
  alert(this.value);
};

There is one good reason to put functions inside the constructor instead of using the prototype chain: making pseudo-private variables and getter/setter functions. See more here.

As for how to name those two ways of binding methods to an object, functions declared inside the constructor are privileged methods while those declared with the prototype pattern are called public methods. You can use both on a single class.

Community
  • 1
  • 1
Domino
  • 6,314
  • 1
  • 32
  • 58
  • 1
    And although possibly beyond the scope of the question methods added directly to the constructor function are essentially static methods `function Thing() { /*returns a new thing*/}; Thing.someStaticFn = function(){}; Thing.someStaticFn(); //static method of 'class' Thing.` – Jared Smith Aug 05 '15 at 17:30
1

As pointed out by others, Method 1 is not valid js. Method 1 should probably be written as

function thing() {
    return {
        method1: function(){},
        method2: function(){}
    }
}

known as a factory function, calling it (like any normal function) produces objects with the specified properties. However, every object has its own copy of everything (which is probably unnecessary) so method 3 places shared functionality (methods, constants, etc) into the function's prototype. All of the objects created by calling the function (should be called with the new keyword in contrast to the factory function) will have access to the properties attached to their constructor's prototype (but will all share a pointer to the same property rather than their own copy).

Method 2 is just creating an object literal with the desired attributes, not a 'class' at all.

Method 4 is also not really a 'class' (in any sense of the term) it is known as the Module Pattern and uses a lexical closure to encapsulate the functionality revealing a public API through the returned object/function.

Its also worth reiterating as pointed out above that none of these are truly classes, the ES 6 class keyword is syntactic sugar for method 3.

Jared Smith
  • 19,721
  • 5
  • 45
  • 83