阿里云主机折上折
  • 微信号
Current Site:Index > Basic syntax of the class keyword

Basic syntax of the class keyword

Author:Chuan Chen 阅读数:42154人阅读 分类: JavaScript

ECMAScript 6 introduced the class keyword, making object-oriented programming in JavaScript clearer and more readable. Although class is essentially syntactic sugar over prototype-based inheritance, it provides a syntax closer to traditional object-oriented languages. Below is a detailed breakdown of its syntax features, method definitions, inheritance mechanisms, and related considerations.

Basic Class Definition

The class keyword is used to define a class, with the class name typically following PascalCase naming conventions. Class declarations are not hoisted and must be defined before use.

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

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const john = new Person('John');
john.sayHello(); // Output: Hello, my name is John

The constructor method in the class body is the default constructor, automatically called when an object instance is created using the new command. A class must have a constructor method; if not explicitly defined, the JavaScript engine will add an empty constructor by default.

Instance Methods and Static Methods

Methods defined in a class are instance methods by default and must be called through an instance. The static keyword is used to define static methods, which are called directly on the class.

class MathUtils {
  static square(x) {
    return x * x;
  }

  cube(x) {
    return x * x * x;
  }
}

console.log(MathUtils.square(3)); // 9
const math = new MathUtils();
console.log(math.cube(3)); // 27

In static methods, this refers to the class itself rather than an instance. Static methods are often used to implement utility functions or factory methods.

Property Definition Methods

In ES6 classes, instance properties can be defined directly in the constructor or at the top level of the class using assignment statements. Static properties must be defined outside the class using the class name.

class Rectangle {
  // New instance property syntax
  height = 0;
  
  constructor(width) {
    this.width = width;
  }

  get area() {
    return this.width * this.height;
  }
}

// Static property
Rectangle.version = '1.0';

const rect = new Rectangle(10);
rect.height = 5;
console.log(rect.area); // 50
console.log(Rectangle.version); // '1.0'

Getters and Setters

The get and set keywords can be used to define getter and setter functions for a property, intercepting its access and assignment behavior.

class Temperature {
  constructor(celsius) {
    this.celsius = celsius;
  }

  get fahrenheit() {
    return this.celsius * 1.8 + 32;
  }

  set fahrenheit(value) {
    this.celsius = (value - 32) / 1.8;
  }
}

const temp = new Temperature(25);
console.log(temp.fahrenheit); // 77
temp.fahrenheit = 86;
console.log(temp.celsius); // 30

Class Inheritance

The extends keyword is used to implement inheritance. Subclasses can call the parent class's constructor and methods using the super keyword.

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

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Call the parent class constructor
    this.breed = breed;
  }

  speak() {
    super.speak(); // Call the parent class method
    console.log(`${this.name} barks.`);
  }
}

const dog = new Dog('Rex', 'Labrador');
dog.speak();
// Output:
// Rex makes a noise.
// Rex barks.

Subclasses must call the super method in their constructor; otherwise, an error will occur when creating an instance. This is because the subclass's this object must first be shaped by the parent class's constructor.

Private Properties and Methods

ES2022 officially added private properties and methods to the standard, defined by prefixing the property or method name with #.

class Counter {
  #count = 0; // Private property

  #increment() { // Private method
    this.#count++;
  }

  tick() {
    this.#increment();
    console.log(this.#count);
  }
}

const counter = new Counter();
counter.tick(); // 1
counter.tick(); // 2
console.log(counter.#count); // Error: Private field '#count' must be declared in an enclosing class

Class Considerations

  1. Classes default to strict mode internally.
  2. Classes are not hoisted.
  3. Class methods are non-enumerable.
  4. All instances of a class share the same prototype object.
  5. The new.target property can be used to determine how the constructor was called.
class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('This class cannot be instantiated');
    }
  }
}

class Rectangle extends Shape {}

const shape = new Shape(); // Error
const rect = new Rectangle(); // Works

Class Expressions

Like functions, classes can also be defined using expressions. The class name in a class expression is only valid inside the class. If omitted, it becomes an anonymous class.

const MyClass = class Me {
  getClassName() {
    return Me.name;
  }
};

const inst = new MyClass();
console.log(inst.getClassName()); // "Me"
console.log(Me); // Error: Me is not defined

Mixin Pattern Implementation

Simple Mixin patterns can be implemented using class inheritance, a technique for combining the functionality of multiple classes into one.

const Serializable = Base => class extends Base {
  serialize() {
    return JSON.stringify(this);
  }
};

const Loggable = Base => class extends Base {
  log() {
    console.log(this.toString());
  }
};

class Person {
  constructor(name) {
    this.name = name;
  }
  
  toString() {
    return `Person: ${this.name}`;
  }
}

const EnhancedPerson = Serializable(Loggable(Person));
const person = new EnhancedPerson('Alice');
person.log(); // "Person: Alice"
console.log(person.serialize()); // "{"name":"Alice"}"

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.