Maison > interface Web > js tutoriel > POO en JS -

POO en JS -

WBOY
Libérer: 2024-09-03 21:08:26
original
857 Les gens l'ont consulté

OOP in JS -

  • Les classes JS sont comme du sucre syntaxique, pas les mêmes que les classes d'autres langages fortement typés.
  • Ajoute uniquement un emballage syntaxique pour le rendre familier aux développeurs provenant d'autres langages.
  • les classes sont un type spécial de fonctions en coulisse, elles peuvent donc être écrites sous forme d'expression de classe ainsi que de déclaration de classe.
## 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'
Copier après la connexion

Points d'imposition :

  • Les déclarations Fn sont levées tandis que les déclarations Class ne sont PAS levées.
  • Également citoyen de première classe, tout comme Fns, c'est-à-dire qu'il peut être transmis et renvoyé depuis Fns.
  • Le corps de classe est toujours exécuté en mode strict, que l'on active ou non le mode strict.
  • Les classes rendent le code plus propre, avec un bruit de caractère réduit, à condition que vous sachiez comment il est implémenté sous le capot. ** Pour devenir un expert en JS, vous devez comprendre les détails complexes de mise en œuvre du langage, comme avec les cours.

Propriétés de l'accesseur : getters et setters, c'est-à-dire des fns qui obtiennent et définissent la valeur. Mais de l’extérieur, ils ressemblent toujours à des propriétés ordinaires.

Les propriétés normales sont appelées propriétés des données.

  • Les getters et settters sont communs à tous les objets dans JS, c'est-à-dire que chaque objet peut avoir des propriétés getter et setter. Ces getter-setter sont appelés propriétés d'accesseur, tandis que les propriétés normales sont appelées propriétés de données.

- Getter & setter sont des fns qui obtiennent et définissent une valeur, qui, de l'extérieur, ressemblent à des propriétés normales.

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.
Copier après la connexion

Méthodes statiques

Ex. Array.from() = Convertit une structure de type tableau en tableau.
Array.from(document.querySelector('h1'));
Array.from(document.querySelectorAll('h1'));

Ex. .from est attaché au constructeur Array, pas à la propriété prototype du constructeur. Par conséquent, tous les tableaux n'héritent pas de ce fn.
[1,2,3].from(); // .from n'est pas une fonction

Ex. Number.parseFloat(12) est une méthode statique sur le constructeur Number, non disponible sur les variables numériques.

Création d'une méthode statique.

// 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
Copier après la connexion

Objet.create() :

Utilisé manuellement pour définir le prototype de notre objet sur n'importe quel objet que nous voulons.
Sera utilisé pour implémenter les classes d'héritage n/b.
Héritage prototypique implémenté à l'aide de ce fn.
Object.create renvoie un objet vide.
Fonctionne d'une manière différente selon laquelle les fns et les classes du constructeur fonctionnent.
Il existe toujours une idée d'héritage prototypique, même sans l'implication des opérateurs "prototype", "constructeur ()", "nouveau".

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();

Copier après la connexion

Constructeur Fn --(.prototype)--> Personne.prototype
Instance d'objet --(proto)--> Personne.prototype

Fonctionne exactement comme cela fonctionnait pour les constructeurs fn ou dans les classes
Pas besoin de propriété constructor() ou .prototype pour atteindre cet objectif.

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 }  
Copier après la connexion

Façons de créer un héritage prototypique :
Constructeur Fn
Cours ES6
Objet.create

Héritage entre classes utilisant constructor() :

Toutes ces techniques permettent à un objet de rechercher des méthodes sur son prototype.
Les vraies classes n'existent pas en 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'
Copier après la connexion

Suppression du code redondant de l'exemple ci-dessus :

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'
Copier après la connexion

'new' fait automatiquement un lien entre l'instance d'objet et son prototype via proto
L'idée générale de l'héritage est que la classe enfant peut partager le comportement des classes parents en amont de la chaîne de prototypes.
Prototype[Object.prototype] = null ; // Se trouve au sommet de la chaîne prototype.

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
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal