Home > Web Front-end > JS Tutorial > body text

OOP in JS -

WBOY
Release: 2024-09-03 21:08:26
Original
779 people have browsed it

OOP in JS -

  • JS classes are like syntactic sugar, not the same as classes of other strongly typed languages.
  • Only adds syntax-wrapping to make it familiar for devs coming from other languages.
  • classes are a special type of functions behind the scenes, hence can be written as class expression as well as class declaration.
## class expression:
const Person = class {
}

## class declaration:
class Person {
  constructor(fName, bYear){
   this.fName = fName;
   this.bYear = bYear;
  }
  calcAge(){
   console.log(2024 - this.bYear);
  }
}

- constructor is a method of this class. Pass values for properties to have in objects created using this fn.
- then set the properties of the object using this.xxx = xxx;
- On using 'new' operator, this constructor will be called automatically and return a new object which will be stored in LHS variable as shown below.
Ex. const ronald = new Person('ronald',1975); // Person { fName: 'ronald', bYear: 1975 }
- Methods are written outside the constructor fn and will be added to the prototype property of the object which can be verified using devConsole.
Ex. ronald.calcAge(); // 49

ronald.__proto__ === Person.prototype; // true

- No commas need to be added while adding multiple methods below the constructor fn inside the class.

## Hence, the above syntax works same as constructor fn syntax but with a familiar syntax of strongly typed class based languages.

## Adding a fn explicitly to the prototype:
Person.prototype.greet = function(){
console.log(`Hey ${this.fName}`);
}
ronald.greet(); // 'Hey ronald'
Copy after login

Impt Points:

  • Fn declarations are hoisted while Class declarations are NOT hoisted.
  • Also first class citizen just like Fns i.e can be passed-to & returned-from fns.
  • Body of class is always executed in strict mode whether we activate the strict mode or not.
  • Classes make the code look cleaner, with reduced character noise provided you know how its implemented under the hood. ** To become an expert in JS, you need to understand the intricate language implementation details like with classes.

Accessor Properties: Getters & Setters i.e fns that get & set the value. But on the outside, they still look like regular properties.

Normal Properties are called Data Properties.

  • Getters & Settters are common to all objects in JS i.e every object can have getter and setter property. These getter-setter are called as accessor properties, while normal properties are called as data properties.

- Getter & setter are fns that get and set a value, from outside look like normal properties.

const account = {
  owner: 'jonas',
  movements: [200,300,100,500],
  get latest(){
    // will return an array with last value. Hence, use pop to get the value.
    return this.movements.slice(-1).pop();
  },
  set latest(mov){
    this.movements.push(mov);
  }
}

account.latest; // 500
account.latest = 50; 
account.latest; // 50

Just like above, classes also support the getter-setter methods but acccessed like using a property syntax.

These are very useful for data validation.
Copy after login

Static Methods

Ex. Array.from() = Converts array-like structure to array.
Array.from(document.querySelector('h1'));
Array.from(document.querySelectorAll('h1'));

Ex. .from is attached to the Array construcutor, not to the prototype property of the constructor. Hence all arrays don't inherit this fn.
[1,2,3].from(); // .from is not a function

Ex. Number.parseFloat(12) is a static method on Number constructor, not available on number variables.

Creating a static method.

// Static methods are not inherited. They are not added to prototype.
className.fnName = function(){
  console.log(this); // Entire constructor() which is calling the method
  console.log("JS is awesome")
};
className.fnName();

// Rule =  whatever object is calling the method, 'this' points to that object inside the fn. Hence its simply the entire constructor() above.

//Inside class, we need to use static keyword for adding a static method.
static fnName = function(){
  console.log(this); // can point to the entire class defn
  console.log("JS is awesome")
};

// Static methods and instance methods will be different from each other.
// instance methods will be prototype, hence all instances can have access to them
Copy after login

Object.create():

Manually used to set prototype of our object to any object that we want.
Will be used to implement inheritance b/w classes.
Prototypal Inheritance Implemented using this fn.
Object.create returns an empty object.
Works in a different way in which constructor fns and classes work.
Still there is idea of prototypal inheritance, even without involvement of 'prototype', 'constructor()', 'new' operator.

const PersonProto = {
  // This method will be looked up using __proto__ link
  calcAge(){
    console.log(2024 - this.bYear);
  }
};

// baba will be created, with its prototype set to PersonProto object.
const baba = Object.create(PersonProto);
baba;

baba.name = 'Roger';
baba.bYear = '2000';
baba.calcAge();

Copy after login

Constructor Fn --(.prototype)--> Person.prototype
Object Instance --(proto)--> Person.prototype

Works just like it worked for fn constructors or in classes
No need of constructor() or .prototype property to achieve this goal.

const PersonProto = {
  // This method will be looked up using __proto__ link
  calcAge(){
    console.log(2024 - this.bYear);
  },
  // Noting special with init name, its a normal fn here.
  // This has nothing to with ES6 constructor()
  // Manual way of initialzing an object.
  init(fName, bYear){
    this.fName = fName;
    this.bYear = bYear;
  }
};

// baba will be created, with its prototype set to PersonProto object.
const baba = Object.create(PersonProto);
baba;

baba.name = 'Roger';
baba.bYear = '2000';
baba.calcAge();

baba.__proto__;    // { calcAge: [Function: calcAge] }
baba.__proto__ === PersonProto; //true


const alice = Object.create(PersonProto);
alice.init("alice", 2000);
alice;   // { fName: 'alice', bYear: 2000 }  
Copy after login

Ways to create Prototypal Inhertitance:
Constructor Fn
ES6 Classes
Object.create

Inheritance between Classes using constructor():

All of these techniques allow object to lookup for methods on its prototype.
Real classes do not exist in JS.

const Person = function(firstName, bYear){
  this.firstName = firstName;
  this.bYear = bYear;
};

Person.prototype.calcAge = function(){
  console.log(2024 - this.bYear);
};

const Student = function(firstName, bYear, course){
  // This is the duplicate code, any change in Person won't be reflected here.
  this.firstName = firstName;
  this.bYear = bYear;
  this.course = course;
};

Student.prototype.introduce = function(){
  console.log(`My name is ${this.firstName} and I study ${this.course}`);
}

const matt = new Student("Matt", 2000, "CSE");
matt.introduce(); //  'My name is Matt and I study CSE'
Copy after login

Removing redundant code from above example:

const Person = function(firstName, bYear){
  this.firstName = firstName;
  this.bYear = bYear;
};

Person.prototype.calcAge = function(){
  console.log(2024 - this.bYear);
};

const Student = function(firstName, bYear, course){
  // Person(firstName, bYear); -> This doesn't work because we are calling it as a regular fn call. 'new' has to be used to call this fn constructor. This fn call is simply a regular fn call, in which 'this' is set 'undefined'. Hence, an error as it cannot set firstName on undefined.
  // We want to set the 'this' inside this fn to be same as inside Person above.
  Person.call(this, firstName, bYear);
  this.course = course;
};

Student.prototype.introduce = function(){
  console.log(`My name is ${this.firstName} and I study ${this.course}`);
}

const matt = new Student("Matt", 2000, "CSE");
matt.introduce(); //  'My name is Matt and I study CSE'
Copy after login

'new' makes a link automatically between object instance and its prototype via proto
Whole idea of inheritance is that child class can share behavior from parent classes up the prototype chain.
Prototype[Object.prototype] = null; // Sits on top of prototype chain.

const Person = function(firstName, bYear){
  this.firstName = firstName;
  this.bYear = bYear;
};

Person.prototype.calcAge = function(){
  console.log(2024 - this.bYear);
};

const Student = function(firstName, bYear, course){
  Person.call(this, firstName, bYear);
  this.course = course;
};

// Student.prototype = Person.prototype; => This doesn't work because we won't get the prototype chain, rather we will get 
// Constructor fn[i.e Person()]    --------------> Person.prototype
// Constructor fn[i.e Student()]   --------------> Person.prototype
// Object [Matt] __proto__: Student.prototype ---> Person.prototype

// Student.prototype manually linked for lookup to Person.prototype.
// This has to be done here and not after else Object.create will overwrite any of the existing methods like introduce() on it.
Student.prototype = Object.create(Person.prototype);

Student.prototype.introduce = function(){
  console.log(`My name is ${this.firstName} and I study ${this.course}`);
}

const matt = new Student("Matt", 2000, "CSE");
matt.introduce(); //  'My name is Matt and I study CSE'
matt.calcAge();    // 24

matt.__proto__;                   // Person { introduce: [Function (anonymous)] }
matt.__proto__.__proto__;        // { calcAge: [Function (anonymous)] }
matt.__proto__.__proto__.__proto__;   // [Object: null prototype] {}

Student.prototype.constructor = Student;   // [Function: Student]

matt instanceof Student; // true
matt instanceof Person; // true
matt instanceof Object; // true
Copy after login

The above is the detailed content of OOP in JS -. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!