Search This Blog

2024/04/05

Javascript:Class

What is mean by class ?

Classes are one of the features introduced in the ES6 version of JavaScript. A
class is a blueprint for the object. You can create an object from the class.

You can think of the class as a sketch (prototype) of a house. It contains all
the details about the floors, doors, windows, etc. Based on these descriptions,
you build the house. House is the object.Since many houses can be made from the
same description, we can create many objects from a class.

JavaScript still follows a prototype-based inheritance model. Classes in
JavaScript are syntactic sugar over the prototype-based inheritance model which
we use to implement OOP concepts.

Before classes, we used constructor functions to do OOP in JavaScript.

Creating JavaScript Class: We can create the class with the help of the class
keyword.

Code:
//using javascript classes
class Pen {
constructor(name, color, price){
this.name = name;
this.color = color;
this.price = price;
}
showPrice(){
console.log(`Price of ${this.name} is ${this.price}`);
}
}

const pen1 = new Pen("Marker", "Blue", "$3");
pen1.showPrice();

The properties are assigned in a constructor function.Here name,color,
price properies are assigned in constructor above.pen1 is is an object of
class Pen.It is easy to define methods in the JavaScript class. You simply
give the name of the method followed by ().Here showPrice() is a method
in javascript class Pen.To access the method of an object, you need to
call the method using its name followed by () over object of class.
e.g. In
pen1.showPrice();
the pen1 is object of class Pen & we are calling showPrice() for object
pen1.

Above class implementation can be recreated by using "constructor
function" as per old syntax as follows.
//using constructor function.
Code:
function Pen(name, color, price) {
this.name = name;
this.color = color;
this.price = price;
}

const pen1 = new Pen("Marker", "Blue", "$3");

Pen.prototype.showPrice = function(){
console.log(`Price of ${this.name} is ${this.price}`);
}

pen1.showPrice();

the constructor function code just above can be rewritten as follows

Code:
function Pen(name, color, price) {
this.name = name;
this.color = color;
this.price = price;

this.showPrice = function(){
console.log(`Price of ${this.name} is ${this.price}`);
}
}
const pen1 = new Pen("Marker", "Blue", "$3");
pen1.showPrice();

Both code are practically doing same thing.

Getters and Setters: In JavaScript, getter methods get the value of an object
and setter methods set the value of an object. JavaScript classes may include
getters and setters. You use the get keyword for getter methods and set for
setter methods. e.g.

Code:

class Person {
constructor(name) {
this.name = name;
}

// getter
get personName() {
return this.name;
}

// setter
set personName(x) {
this.name = x;
}
}

let person1 = new Person("Jack");
console.log(person1.personName);
console.log(person1.name);

// changing the value of name property
person1.personName = "Sarah";
console.log(person1.name);
Explanation: when we call console.log(person1.personName); we are using getter.
when we call person1.personName = "Sarah"; we are using setter. Please note
that console.log(person1.name); person1.name = "bob"; these two line
still work as name is public property in class Person.

Private property: As we have seen code just above person1.name &
person1.personName are both doing same thing. But want to hide access to
"name" property entirely and only expose it through "personName" the
getter-setter function for that purpose we need to make our "name" property
as private. To make property or method private we need to prefix it with #.

Code:
class Person {
#name;
constructor(name) {
this.#name = this.#MakeNameUpperCase(name);
}

// getter
get personName() {
return this.#name;
}

// setter
set personName(x) {
this.#name = x;
}

#MakeNameUpperCase(x) {
return x.toUpperCase();
}
}

let person1 = new Person("Jack");
console.log(person1.personName);

// changing the value of name property
person1.personName = "Sarah";
console.log(person1.personName);

Explanation:
#name & #MakeNameUpperCase are respectively private property &
private method in class Person they are not accessible outside of
class,means they can not be called on object created from class.

Hoisting: A class should be defined before using it. Unlike functions and other
JavaScript declarations, the class is not hoisted.

Code: // accessing class const p = new Person(); // ReferenceError

// defining class
class Person {
constructor(name) {
this.name = name;
}
}
Explanation: As you can see, accessing a class before defining it throws an
error.

'use strict': Classes always follow 'use-strict'. All the code inside the class
is automatically in strict mode.

Code:
class Person {
constructor() {
a = 0;
this.name = a;
}
}

let p = new Person(); // ReferenceError: Can't find variable: a

Explantion:
In contructor we are accessing variable "a" but never declared.

typeof operator: JavaScript class is a special type of function. And the typeof
operator returns function for a class.

Code:
class Person {}
console.log(typeof Person); // function

Static Keyword in Javascript:

The static keyword in JavaScript helps you define
functions and properties in the class that cannot be called by the instance of
the object. They can only be called by the class itself which consists of these
static functions and properties.

Code:
class Person {
#firstName;
#lastName;
#fullName;

constructor(firstName, lastName) {
this.#firstName = this.#MakeNameUpperCase(firstName);
this.#lastName = this.#MakeNameUpperCase(lastName);

this.#fullName = Person.#getFullName(this.#firstName, this.#lastName);
}

// getter
get personName() {
return this.#fullName;
}

//
static #getFullName(firstName, lastName) {
return firstName + " " + lastName;
}

// setter
set personName(fullName) {
let nameParts = fullName.split(" ");
this.#firstName = this.#MakeNameUpperCase(nameParts[0]);
this.#lastName = this.#MakeNameUpperCase(nameParts[1]);
}

#MakeNameUpperCase(x) {
return x.toUpperCase();
}
}

let personObject = new Person("sangram", "desai");
console.log("personName:", personObject.personName);

Explanation: Here getFullName() is static function,if we just keep it static we
can then access it as Person.getFullName("firstName","lastName") what we
have done is prefixed # before it so now its static as well as private.

We can have static property as well as methods.

Code:
class Person {
#firstName;
#lastName;
#fullName;
static #dob;

constructor(firstName, lastName) {
this.#firstName = this.#MakeNameUpperCase(firstName);
this.#lastName = this.#MakeNameUpperCase(lastName);

this.#fullName = Person.#getFullName(this.#firstName,
this.#lastName);
}

// getter
get personName() {
return this.#fullName;
}

//
static #getFullName(firstName, lastName) {
return firstName + " " + lastName;
}

static set Dob(dob) {
Person.#dob = new Date(dob);
}

static getAge() {
let date = new Date();
let millSecondDifference = date - Person.#dob;
let diffInYear = Math.floor(millSecondDifference / 31536000000);
return diffInYear;
}

// setter
set personName(fullName) {
let nameParts = fullName.split(" ");
this.#firstName = this.#MakeNameUpperCase(nameParts[0]);
this.#lastName = this.#MakeNameUpperCase(nameParts[1]);
}

#MakeNameUpperCase(x) {
return x.toUpperCase();
}
}

let personObject = new Person("sangram", "desai");
console.log("personName:", personObject.personName);

Person.Dob = "1981-04-26";
console.log("Age:", Person.getAge());

Here #dob is static private property while Dob is static setter.

Accessing this inside static function:
Code:
class Person {
static petName;

constructor(firstName) {
this.firstName = firstName;
Person.petName = firstName.substring(0,3)
}

static get First() {
return Person.petName;
}

logInstanceObject(){
console.dir(this)
}

static logStaticObject(){
console.dir(this)
}

static set First(name) {
Person.petName = name;
}
}

let personObject = new Person("sangram")
Person.First ="SAN"
console.log("First:",Person.First)

Person.logStaticObject()
personObject.logInstanceObject()

Output: First: SAN [class Person] { petName: 'SAN' } Person { firstName:
'sangram' }

Explanation: logInstanceObject,logStaticObject are two method one is static &
other is non-static with same code but even after both printing this we are
getting different output.Person

static private property & getter and setter:
Code:
class Person {
static #firstName;
constructor() { }

get FirstName() {
return Person.#firstName;
}

set FirstName(name) {
Person.#firstName = name;
}
}

let personObject = new Person()
Person.FirstName = "sagar"
console.log("First:",Person.FirstName)

Person.FirstName ="sachin"
console.log("Second:",Person.FirstName)
Output: First: sagar Second: sachin

Explanation: Here firstName is defined as static & private while getter & setter
are not private.

Two variables in class with same name one static other non-static:
Code:
class ShoppingCart {
static items = [];
items=[];

static addProduct(product) {
this.items.push(product);
}

static showProduct() {
console.log(this.items)
}

addProduct(product) {
this.items.push(product);
}

showProduct() {
console.log(this.items)
}
}
ShoppingCart.addProduct("Some Book")
ShoppingCart.showProduct()

let ShoppingCartObject = new ShoppingCart()
ShoppingCartObject.addProduct('New Book')
ShoppingCartObject.showProduct()

Output:
[ 'Some Book' ]
[ 'New Book' ]

Explanation: Two variable items are one static other non-static are treated as
different from each other. adding value in one doesn't affect other.

Can we define two variable with same name both private but one static & other
non static?

Code:
class ShoppingCart {
static #items = [];
#items=[];

static addProduct(product) {
this.#items.push(product);
}

static showProduct() {
console.log(this.#items)
}

addProduct(product) {
this.#items.push(product);
}

showProduct() {
console.log(this.#items)
}
}
ShoppingCart.addProduct("Some Book")
ShoppingCart.showProduct()

let ShoppingCartObject = new ShoppingCart()
ShoppingCartObject.addProduct('New Book')
ShoppingCartObject.showProduct()

Output: SyntaxError: Identifier '#items' has already been declared

Explanation: items variable defined twice once as private & second time as
static private but we get error.

private getter setter but one is static will it work ?

Code: class Example {
#_prop;
constructor(){
this.#prop ="Human"
}

get #prop() {
return this.#_prop;
}

static set #prop(value) {
}
}

Output: SyntaxError: Identifier '#prop' has already been declared

Explanation: Here we are trying to define private getter setter but one is
static and other is non-static which is not allowed. If we tremoved static
from setter or added static to getter also we will not get this error. Note:
Private getters and setters for the same name must either be both static, or
both non-static. This limitation does not exist for public methods.

No comments:

Post a Comment