116

I was wondering - what's the difference between JavaScript objects, classes and functions? Am I right in thinking that classes and functions are types of objects?

And what distinguishes a class from a function? Or are they really the same thing, just the term for them changes according to how they are used?

function func() { alert('foo'); } // a function
func(); // call the function - alerts 'foo'
var func2 = function () { alert('hello'); } // acts the same way as 'func' surely?
func2(); // alerts 'hello'

var Class = function() { alert('bar'); }; // a class
var c = new Class(); // an istance of a class - alerts 'bar'

Sure, classes have methods and properties and can be instantiated - but then, I could do the same with any old function - or not?

Sean Bone
  • 3,368
  • 7
  • 31
  • 47
  • 14
    Classes have been introduced in ECMA 6 as of late: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes – MathuSum Mut Jun 13 '16 at 12:01
  • 7
    Classes are now common in many post node.js Javascript libraries, etc. It's no longer correct to say *there are no classes in Javascript*. There are now classes, these are not well supported by browser implementations (yet) but in the age of NPM and Node.js classes are very much a core concept of the language moving forward (this is all just an FYI I appreciate at the time of writing the first comment here was correct). – Liam Oct 16 '17 at 12:49

7 Answers7

97

As you must already be aware by now there are no classes in JavaScript. Instead functions in JavaScript may be made to behave like constructors by preceding a function call with the new keyword. This is known as the constructor pattern.

In JavaScript, everything is an object except for the primitive data types (boolean, number, and string), and undefined. On the other hand null is actually an object reference even though you may at first believe otherwise. This is the reason typeof null returns "object".

Functions in JavaScript are similar to functables in Lua (i.e. they are callable objects). Hence a function can be used in place of an object. Similarly, arrays are also objects in JavaScript. On the other hand, objects can be thought of as associative arrays.

The most important point however is that there are no classes in JavaScript because JavaScript is a prototypal object-oriented language. This means that objects in JavaScript directly inherit from other objects. Hence we don't need classes. All we need is a way to create and extend objects.

Read the following thread to learn more about prototypal inheritance in JavaScript: Benefits of prototypal inheritance over classical?

Henry Obiaraije
  • 301
  • 3
  • 10
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • 1
    Thank you very much for your answer! I have read around the subject, and I think I get it now. So you advise using the prototypal pattern over the constructor pattern? – Sean Bone Jul 08 '13 at 17:50
  • 1
    @SeanBone: I advise learning the prototypal pattern before learning the constructor pattern because it makes it easier to understand prototypal inheritance. However the constructor pattern is faster than the prototypal pattern in JavaScript. Hence if you want to write performance critical code then using the constructor pattern makes more sense. Nevertheless the prototypal pattern is still pretty fast and rest assured you will hardly ever need extra performance boost. JavaScript interpreters do a great job of optimizing code. Hence most of the time you should stick with the prototypal pattern. – Aadit M Shah Jul 09 '13 at 03:04
  • @AaditMShah I would like to correct you on `In JavaScript everything is an object except for the primitive data types (boolean, number and string)`. In JavaScript `boolean, number and string` starts with upper case like `Boolean, Number and String`. And they are all inherited from `Object` eventually. Everything in JavaScript except `undefined` inherits from `Object` (in the end of inheritance chain atleast). – bits Jul 09 '13 at 19:03
  • 2
    @bits I'm afraid that you are wrong. You see there are two types of booleans, numbers and strings in JavaScript - primitives and wrapped objects. Literal values in JavaScript are treated as primitives. For example the literals `true`, `3.14` and `"Hello World!"` are all primitive data types. When you use `typeof` on them they return `"boolean"`, `"number"` and `"string"` respectively. However JavaScript allows you to use them as objects and coerces them to objects whenever required. Hence you can do things like `"abc".slice(-1)`. This is the reason we have the `valueOf` operator in JavaScript. – Aadit M Shah Jul 10 '13 at 01:48
  • @bits Read the following blog post: http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/ – Aadit M Shah Jul 10 '13 at 01:50
  • @AaditMShah I now realize that I was wrong. Thanks for explaining me nicely. Good thing that I commented, otherwise I never would have known. – bits Jul 10 '13 at 04:18
  • @AaditMShah In my edit I changed 'prototypal' to 'prototypical' by mistake, could you revert that please? – Xiao Dec 22 '14 at 05:27
  • 38
    This answer is now out of date – Liam Oct 16 '17 at 12:47
  • 1
    @Liam, so the updated answer is by Neoaptt(Update 2015), right? – Dhaval Jardosh Nov 01 '17 at 14:36
  • 2
    Yes @DhavalJardosh – Liam Nov 01 '17 at 15:22
  • 3
    null is one of primitive values. It is not an object. typeof null === "object" is simply a bug in JS for nearly two decades. – Infinity Challenger Sep 11 '18 at 11:54
  • 3
    null is a primitive value. – Emilio Grisolía May 27 '20 at 20:43
51

Update 2015

There are classes in JavaScript they just aren't used on older browsers:

Compatibility screenshot

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

It has constructors, extensions, and the like.

class Cat { 
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Lion extends Cat {
  speak() {
    super.speak();
    console.log(this.name + ' roars.');
  }
}
Daniel_Knights
  • 7,940
  • 4
  • 21
  • 49
Roger
  • 3,226
  • 1
  • 22
  • 38
  • 7
    I think it's important to not that the new class constructors are part of the newest JavaScript so are only supported as such and they are only a new syntax they are in fact functions they are just designed as syntactical sugar to make the code more organized they don't work any different then the function constructors. – Binvention Feb 01 '16 at 06:30
  • 3
    These are still not "classes" in the classical inheritance sense but merely syntactical sugar used to wire up objects linked to other objects (OLOO) in such a way as to approximate the behaviour of classical inheritance. There are no classes in JavaScript despite the keyword giving you this illusion. – Andy Fusniak Sep 01 '17 at 16:45
  • @Andy Fusniak The OP never mentioned the term “classical inheritance sense”. He asked what the difference is between a class & an object in JavaScript. I would say that if there is a ‘class’ keyword in JavaScript, then classes exist, even if they don’t adhere to classes in the classical sense. – Charles Robertson Feb 08 '22 at 09:48
  • @CharlesRobertson I commented here specifically because the code example given uses inheritance (Lion extends Cat). Adding a keyword into language years after its creation doesn’t magically make that paradigm appear in the language. The virtual machine is built using an OLOO model. There are no classes in JavaScript - just a class keyword that wires objects together. It behaves nothing like a class based language, i.e. “classes”. – Andy Fusniak Feb 08 '22 at 16:45
26

A Class in JS:

function Animal(){  

    // Private property
    var alive=true;

    // Private method
    function fight(){ //... }   

    // Public method which can access private variables
    this.isAlive = function() { return alive; } 

    // Public property
    this.name = "Joe";
}

// Public method
Animal.prototype.play = function() { alert("Bow wow!"); }

// .. and so on

Now when you create its object:

var obj = new Animal();

You can expect anything of this object as you would from objects in other language. Just the efforts to achieve it was a bit different. You should also be looking at inheritance in JS.


Getting back to your question, I'll reword it as:

//Class  : A representation of a set with common properties.
//object : One from the set with the same properties.


var Class = function() {alert('bar');}; // A set of function which alert 'bar'
var object = new Class();               // One of the functions who alert's 'bar'.
Mike Lowery
  • 2,630
  • 4
  • 34
  • 44
loxxy
  • 12,990
  • 2
  • 25
  • 56
  • 3
    Prototype based programming is not "a way people found out to emulate object oriented practices". It **is** one way of object oriented programming, invented long before JavaScript, and an alternative to class based programming. – a better oliver Jul 08 '13 at 12:22
13

JavaScript does not have classes, and functions are actually objects in JavaScript (first-class citizens). The only difference that function objects have is that they are callable.

function func() { alert('foo'); } // a function - Correct

func(); // call the function - alerts 'foo' - Correct

var func2 = function () { alert('foo'); } // same as 'func' surely? - Nope, func2 is a different object, that apparently does the same thing when called.

var Class = function() { alert('bar'); }; - It's a function with no name stored in variable Class.

var c = new Class(); - Calls function stored in Class supplying new empty object as this and returning that object. Functions called as new functionA() are expected to work as constructors and prepare a newly created object (this). In your case - constructor does nothing with the object and just alerts bar.

mishik
  • 9,973
  • 9
  • 45
  • 67
6

There are no classes in javascript. But, there are ways to make a function to behave like a class in other languages.

A very good explanation is given here 3 way to define a class in js

Also, found a very good reference for OOP in Javascript

Tala
  • 8,888
  • 5
  • 34
  • 38
  • 1
    As of ECMAScript 2015 there **are** classes in Javascript – Liam Nov 01 '17 at 15:24
  • @Liam It is syntactic sugar. It's still a function under the hood. – Nikita Shahov Jun 29 '19 at 06:46
  • 3
    @NikitaShahov -- that's just _how classes are implemented in javascript_ and doesn't mean there aren't classes. Even private members are about to become a thing now. (it's a stage 3 proposal: https://github.com/tc39/proposal-private-methods) – Faust Dec 23 '19 at 19:38
6

You also get classes in ES6 that look like this:

//class
class Cat {
    //constructor
    constructor() {
        this.name = 'Snowball';
    }

    //method
    meow() {
        console.log('Hello, nyah! My name is ' + this.name + ' nyah!~');
    }
};
sorak
  • 2,607
  • 2
  • 16
  • 24
4

Object is the base type in JavaScript i.e. all the user defined data types inherits from Object in one way or another. So if you define a function or a class [note as of now JS doesn't support class construct, but its proposed in ECMAScript version 6], it will implicitly inherit from Object type.

Classes are really used for encapsulating logical functions and properties into one type / entity and you can 'new' it up using constructor syntax. So if you define a 'Customer' class, you can instantiate it multiple times and each instance / object can have different values. They can even share the values if you define class level value using prototype.

Since JS doesn't support class construct at the moment, functions can really act as individual method as well as container for other functions or types.

I hope with ECMAScript 6 we will have clear separation between these constructs similar to what we have in other languages like C#, Java etc.

Prasad Honrao
  • 211
  • 3
  • 18