1

Coming from a Python background, I've read this, learning Javascript:

Classes are in fact "special functions", and just as you can define function expressions and function declarations, the class syntax has two components: class expressions and class declarations.

on dev.mozilla website..

What I understand is that :

  • Functions are objects in OOP

  • And not classes are functions.

  • And maybe classes themselves are objects. I am not sure.

Am I wrong?

  • 3
    A JavaScript class declaration creates a constructor function, using the class name as its name. The contents of the class declaration initializes the constructor prototype and creates the actual body of the function. So, in effect, yes, a class declaration creates a function. – Pointy Sep 04 '21 at 12:10
  • In JS, classes are functions and functions are objects. However, you have to use `new` when instantiating a `class`. You cannot call a `class` like a normal function. – Sebastian Simon Sep 04 '21 at 12:14
  • Thank God. I'm sorry if I was a bit lazy about a little deep search. Now I've pretty much understood. I'm a very beginner in JavaScript, so I had to make a search to understand some of the terms you've used. Thanks! – Omar AlHadidi Sep 04 '21 at 12:47
  • @SebastianSimon But what is the purpose of `class` keyword if there is `function`? The console accepts it in FireFox. – Omar AlHadidi Sep 04 '21 at 12:59
  • 1
    @OmarAlHadidi See [javascript: what's the difference between a function and a class](/q/11970141/4642212). Do note the comments about outdated answers by T.J. Crowder. If you want something like classes you should always prefer the `class` keyword. If you want something like normal functions you should either use methods or arrow functions. A `function` can behave both as a normal functions or as a limited form of classes (e.g. subclassing native classes not fully possible, no private fields, …), and they’re no longer very useful (before ECMAScript 2015, it was the only kind of function). – Sebastian Simon Sep 04 '21 at 13:11
  • @SebastianSimon ... Is that stuff in python also, which is that a class is a function, and a function is an object? – Omar AlHadidi Sep 04 '21 at 17:21

1 Answers1

2

Classes are indeed functions, and functions are also objects - you can put arbitrary key-value pairs onto functions, just like onto objects.

class X{}

console.log(typeof X);
console.log(X instanceof Object);

That's a class declaration. A class expression is like:

const TheX = class X{}

console.log(typeof TheX);
console.log(TheX instanceof Object);

When a class has key-value pairs directly on it (like an object), the properties are generally called "static":

class X{
  static prop = 'foo';
}

console.log(X.hasOwnProperty('prop'));

Classes created with class can't be invoked without new, but classes created with function can (in which case it's equivalent to a standard function).

function X() {
}

// As a class:
const x = new X();

// As an ordinary function:
const somethingElse = X();

With function syntax, whether the function behaves as a class or as a plain function is determined by the caller - by whether new is used or not. If new is used, this inside the function is set to be an object inheriting from X.prototype, which is automatically returned at the end. If new isn't used, this inside the function is set to the calling context if there is one (eg someObj.X() will have this be someObj).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • And the main difference between function and a class is that `this` in class points to class itself object, while in function it points to it's parent? – vanowm Sep 04 '21 at 12:16
  • 1
    Kind of, the `this` is determined by how it's called. `new X()` calls X like a class, giving it a `this` of an object inheriting from `X.prototype`. `X()` (when X is declared with function syntax rather than `class` syntax) results in it behaving just like an ordinary function. – CertainPerformance Sep 04 '21 at 12:24
  • @OmarAlHadidi ... A class declaration could be more compared to an [immediately invoked function expression](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) which returns the `constructor` function. Thats the reason why a *class* declaration can not be [hoisted](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function#function_declaration_hoisting). – Peter Seliger Sep 04 '21 at 13:12
  • @PeterSeliger They're not hoisted because (1) inline with `let` and `const` of ES6, it's not intuitive and would be bug-prone (2) class declarations can have side-effects (in their static properties) – CertainPerformance Sep 04 '21 at 13:15
  • @CertainPerformance Thanks, I got it. But I wanted to know.. Is it right to define a class, whether it is a declaration or an expression, with empty brackets (The curly ones)? Or you were writing it like this as an example only? – Omar AlHadidi Sep 04 '21 at 18:25
  • @OmarAlHadidi That was just an example of the simplest possible class. An actual class would have useful logic inside, such as a constructor and methods. – CertainPerformance Sep 04 '21 at 18:27
  • To make sure that any beginner, like me, reads this question would not have a wrong understanding. – Omar AlHadidi Sep 04 '21 at 18:29
  • @CertainPerformance yes. This means that it is correct to make an empty class in JS. Have I understood right? Sorry, if I'm noising you. – Omar AlHadidi Sep 05 '21 at 06:31
  • @OmarAlHadidi You probably would not ever do it in real code, because it'd be pointless - it's just an example. Feel free to imagine the class as populated by whatever logic you actually wanted to implement (which is beyond the scope of the question and irrelevant anyway). – CertainPerformance Sep 05 '21 at 13:10