So I am learning NodeJs and while creating a costum module which stores user data I created a constructor function in user.js
function User(name,age){
this.name = name;
this.age = age;
}and in app.js I did
const User = require(//Path);
const user1 = new User("Adam",20);
console.log(user1.name);
but my consfusion begans when I used class in user.js like
class User{
constructor(name,age){
this.name = name;
this.age = age;
}
}but the code in the app.js remained similar with no errors.
So what is the point of classes in javasript? And how are they different form contructor functions.
A class is a constructor technically. Any object with a [[ Construct ]] internal method is considered one. All constructors are functions, but not all functions are constructors.
Functions in Javascript can be of many kinds. We have normal functions, arrow functions, class, methods, async functions, async arrow functions, generators, async generators and possibly in the future generator arrow functions.
Out of all these functions, the only ones who can construct something are class and normal functions. None other of these have a [[ Construct ]] internal method.
There are some semantic differences between normal functions and classes as constructors and as callable functions:
- Only classes have
derivedconstructors (which have a slightly different construction model). - Classes can't be called, only instantiated through
new. - Classes have a
superbinding (which part of it is related to 1). - The prototype of the
class(not theprototypeproperty) is the super constructor when there's anextendsclause. - The
prototypeproperty is not writable in classes, it is writable for normal functions.
Some other things that might be different from class but can be done with normal functions:
classcode is strict mode by default.classuses methods in their prototype. For normal functions as constructors they are typically also regular functions. This mean you can't construct new objects from class methods.classmethods in the prototype are not enumerable. For normal functions as constructors they are typically defined with=and those make the properties enumerable.
Other relevant information:
- Classes are not instantiated until they reach the class declaration/expression. Top level function declarations are initialized right at the start of the function call and are accessible through out the whole scope.
constructor(){ }inclassis the only method definition that actually evaluates to a constructor. Methods are not constructors.
What @Keith said is quite true, and it is, for some odd reason, very hard for JS new-comers to grasp, consider this code:
Old School
With the old school way, things get syntactically messy:
function _Thing() {}
function _Person(name, age, from) {
this.name = name;
this.age = age;
this.from = from;
}
_Person.prototype = Object.create(_Thing.prototype);
_Person.prototype.constructor = _Person;//so easy to mess this up!
_Person.prototype.makeOlder = function () {
this.age++;
};
_Person.prototype.toString = function () {
return this.name;
};
_Person.FLORIDA = 1;
_Person.NEW_YORK = 2;
var _p = new _Person('rafael cepeda', 23, _Person.FLORIDA);
console.log(_p, _p instanceof _Person, _p instanceof _Thing);//_Person { name: 'rafael cepeda', age: 23, from: 1 } true true
New School
The ES6 way provides a very intuitive feeling for OOP programmers:
class Thing {}
class Person extends Thing {
constructor(name, age, from) {
super();
this.name = name;
this.age = age;
this.from = from;
}
makeOlder() {
this.age++;
}
toString() {
return this.name;
}
static get FLORIDA() { return 1; }
static get NEW_YORK() { return 2; }
}
var p = new Person('rafael cepeda', 23, Person.FLORIDA);
console.log(p, p instanceof Person, p instanceof Thing);//Person { name: 'rafael cepeda', age: 23, from: 1 } true true
Notice the parallels between the ES6 style constructor and the old school constructor, take a look at the prototype method definitions; with the new way, you don't even have to write the word prototype (which scares js new-comers).
Because they are essentially the same thing, it is correctly coined syntactic sugar. After inspection of both constructors, it should be no surprise why both typeof's return function.
javascript - Clarification need in class vs constructor function vs factory function - Stack Overflow
[Javascript] When to use classes vs constructor functions?
What's the difference between JS constructor functions and classes?
What is the difference between "class" and "constructor function" in js? I tried looking up on YT but found nothing relevant atlest for me.
Videos
Since it returns an object its a factory function - it's already explained there.
Constuctor functions behaviour different from this, it doesn't return value:
function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation
}
Person.prototype.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};
const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();
I used definition of methods by extending prototype just to separate constructor function, and you can still define a methods inside constructor function as well:
function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation
this.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};
}
const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();
Javascript takes its roots in Prototypal Inheritance:
// Prototype
var ProtoCtr = function ProtoCtr(name, age) {
this.name = name;
this.age = age;
};
ProtoCtr.prototype.printDetails = function printDetails() { console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`); };
var protoInstance = new ProtoCtr('John', 21);
protoInstance.printDetails();
In short:
Functions expose prototypes
Defines a
thiscontext referring to the instanceUse the
newkeyword to create an instance
Then, with ES6, the language offered the possibility to use the class keyword (to please classical OO developers). It's a syntax which allow to group the declaration of your object in a block, avoiding to extend the prototype "manually". Under the hood, it does the exact same thing than the prototypal model, it's just an other way to write it.
// Class
class ClassCtr {
constructor(name, age) {
this.name = name;
this.age = age;
}
printDetails() {
console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`);
}
}
var classInstance = new ClassCtr('John', 21);
classInstance.printDetails();
Key concepts are about the same, but you don't use prototype to expose methods to your instance but declare it directly inside the class block.
Then, there is the factory pattern, which is not a language specs but a pattern, a way to do things. It's my personal favorite. The factory function builds and return the instance. With this method, you get rid of the new keyword and don't need the this anymore to refer to you instance:
// Factory
var factoryCtr = function factoryCtr(name, age) {
var instance = {
name: name,
age: age,
printDetails: function printDetails() { console.log(`Hi, I'm ${instance.name} and I'm ${instance.age} years old`); }
};
return instance;
}
var factoryInstance = factoryCtr('John', 21);
factoryInstance.printDetails();
Even if Class is not covered by this talk, I recommand you to watch this video: https://www.youtube.com/watch?v=ya4UHuXNygM
I hope this helped :)
I know that classes in Javascript are really just "syntactic sugar", as they say, over the prototype model. I come from more of object oriented background and am trying to determine what the difference is/pros and cons of classes vs constructor functions. They seem essentially the same to me, with the exception of the ability to use scope and closures in constructor functions to create "private variables". When should one use classes vs constructor functions? Are they interchangeable in most situations?
So I was reading this article: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
And then I remember that JS also has classes. Now i'm confused what's the difference between the two. I tried searching about JS classes and it turns out they're introduced from ES6. They're defined as template for javascript objects. How is that any different from constructor functions which according to the article above:
The constructor function is JavaScript's version of a class.