In-depth Understanding of ES6 009 [Learning Notes]

Classes in JavaScript function PersonType(name){ this.name = name; } PersonType.prototype.sayName = function(){ console.log(this.name) } var person = new PersonType("Nicholas") p…

Classes in JavaScript

function PersonType(name){  this.name = name;}PersonType.prototype.sayName = function(){  console.log(this.name)}var person = new PersonType("Nicholas")person.sayName(); // outputs "Nicholas"console.log(person instanceof PersonType) // trueconsole.log(person instanceof Object) // true

Class Declarations

class PersonClass {  // 等价于PersonType构造函数  constructor(name){    this.name = name  }  // 等价于PersonType.prototype.sayName  sayName(){    console.log(this.name)  }}let person = new PersonClass("Nicholas");person.sayName(); // outputs "Nicholas"console.log(person instanceof PersonClass) //trueconsole.log(person instanceof Object) // trueconsole.log(typeof PersonClass) // functionconsole.log(typeof PersonClass.prototype.sayName) // function

class is a syntactic sugar. A PersonClass declaration actually creates a function with the behavior of a constructor method. A default iterator can be defined by defining a generator method via Symbol.iterator.

class Collection {
  constructor(){
    this.items = [];
  }

  *[Symbol.iterator](){
    yield *this.items.values()
  }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);

for(let x of collection){
  console.log(x);
}
// 输出:
// 1
// 2
// 3

Static Members

The ES6 class syntax simplifies the process of creating static members. You can use the formal static annotation before a method or accessor property name.

class PersonClass {
  // 等价于PersonType构造函数
  constructor(name){
    this.name = name
  }
  // 等价于PersonType.prototype.sayName
  sayName(){
    console.log(this.name)
  }
  // 等价于等价于PersonType.create
  static create(name){
    return new PersonClass(name)
  }
}
let person = PersonClass.create("Nicholas")

Inheritance and Derived Classes

Implementing inheritance and custom types is a significant task; strict inheritance requires multiple steps.

function Rectangle(length,width){
  this.length = length;
  this.width = width;
}
Rectangle.prototype.getArea = function(){
  return this.length*this.width
}

function Square(length){
  Rectangle.call(this,length,length)
}

Square.prototype = Object.create(Rectangle.prototype,{
  constructor:{
    value:Square,
    enumerable:true,
    writable:true,
    configurable:true
  }
})
var square = new Square(3)
console.log(square.getArea()); // 9
console.log(square instanceof Square) // true
console.log(square instanceof Rectangle) // true

ES6 uses the extends keyword to specify the function a class inherits from. The prototype is automatically adjusted, and the base class's constructor can be accessed by calling the super() method.

class Rectangle {
  constructor(length,width){
    this.length = length;
    this.width = width
  }
  getArea(){
    return this.length*this.width;
  }
}
class Square extends Ractangle {
  constructor(length){
    // Rectangle.call(this,length,length)
    super(length,length)
  }
}
var square = new Square(3)
console.log(square.getArea()); // 9
console.log(square instanceof Square) // true
console.log(square instanceof Rectangle) // true

Classes that inherit from others are called derived classes. If a constructor is specified in a derived class, super() must be called; otherwise, the program will throw an error.

  • super
  • super() can only be used in the constructor of a derived class, not in non-derived classes.
  • super must be called before accessing this in the constructor, as it is responsible for initializing this.
  • If you do not want to call super(), the only way is to have the class's constructor return an object.

Class Method Shadowing

Access in a derived class will always override a method with the same name in the base class. If you want to call the method in the base class, you can use super.getArea().

class Square extends Rectangle {
  constructor(length){
    super(length,length)
  }
  //覆盖并遮蔽Rectangle.prototype.getArea()方法
  getArea(){
    return this.length*this.length
  }
}

Classes Derived from Expressions

Perhaps one of the most powerful aspects of ES6 is the ability to derive classes from expressions. As long as an expression can be resolved to a function with a [[Construct]] property and a prototype, it can be extended using `extends`.

Inheriting Built-in Objects

class MyArray extends Array {
  // 空
}
var colors = new MyArray();
colors[0]="red"
console.log(colors.length) // 1
colors.length = 0
console.log(colors[0]); // undefined

MyArray directly inherits from Array, and its behavior is very similar to Array. Operations on numeric properties update the length property, and operations on the length property also update numeric properties. Thus, you can correctly inherit the Array object to create your own derived array types.

Symbol.species Property

A practical aspect of built-in object inheritance is that methods in built-in objects that originally returned an instance of themselves will automatically return an implementation of the derived class. For example, if you have a derived class MyArray that inherits from Array, methods like slice() will also return an instance of MyArray.

class MyArray extends Array{
  // 空
}
let items = new MyArray(1,2,3,4),
subitems = items.slice(1,3);
console.log(items instanceof MyArray); //true
console.log(subitems instanceof Myarray); // true

Symbol.species is one of several internal Symbols, used to define a static accessor property that returns a function. The returned function is a constructor that must be used whenever an instance of the class is to be created within an instance method (not in the constructor). The following are all Symbol.species implementations that define this property:

  • Array
  • ArrayBuffer
  • Map
  • Promise
  • RegExp
  • Set
  • Typed arrays
// 几个内建类型像这样使用
class MyClass {
  static get [Symbol.species](){
    return this
  }
  constructor(value){
    this.value = value
  }
  clone(){
    return new this.constructor[Symbol.species](this.value)
  }
}

Using new.target in Constructors

class Shape {
  constructor(){
    if(new.target === Shape){
      throw new Error("这个类是不能直接被实例化的")
    }
  }
}
class Rectangle extends Shape {
  constructor(length,width){
    super();
    this.length = length;
    this.width = width;
  }
}
let x = new Shap(); // 抛出错误
let y = new Rectangle(3,4) // 正常执行
console.log(y instanceof Shape) //true

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4335

(0)
Walker的头像Walker
上一篇 Nov 24, 2025 00:00
下一篇 Nov 25, 2025 14:00

Related Posts

  • In-depth Understanding of ES6 013 [Study Notes]

    Code Encapsulation with Modules

    JavaScript loads code using a "share everything" approach to loading code, which is one of the most error-prone and confusing aspects of the language. Other languages use concepts like packages to define code scope. Before ES6, everything defined in every JavaScript file within an application shared a single global scope. As web applications became more complex and the amount of JavaScript code grew, this practice led to issues such as naming conflicts and security concerns. One of ES6's goals was to address the scoping issue…

    Personal Mar 8, 2025
    1.3K00
  • Go Engineer System Course 013 [Study Notes]

    Order transactions, whether deducting inventory first or later, will both affect inventory and orders. Therefore, distributed transactions must be used to address business issues (e.g., unpaid orders). One approach is to deduct inventory only after successful payment (e.g., an order was placed, but there was no inventory at the time of payment). Another common method is to deduct inventory when the order is placed, but if payment isn't made, the order is returned/released upon timeout.

    Transactions and Distributed Transactions
    1. What is a transaction?
    A transaction is an important concept in database management systems. It is a collection of database operations, which either all execute successfully, or all...

    Personal Nov 25, 2025
    39800
  • In-depth Understanding of ES6 002 [Study Notes]

    Strings and Regular Expressions. Strings and Regular Expressions. JavaScript strings have always been built based on 16-bit character encoding (UTF-16). Each 16-bit sequence is a code unit, representing a character. String properties and methods like `length` and `charAt()` are all constructed based on these code units. The goal of Unicode is to provide a globally unique identifier for every character in the world. If we limit the character length to 16 bits, the number of code points will not...

    Personal Mar 8, 2025
    2.0K00
  • Go Engineer Training Course 018 [Learning Notes]

    Getting Started with API Gateway and Continuous Deployment (Kong & Jenkins) corresponds to the course materials "Chapter 2: Getting Started with Jenkins" and "Chapter 3: Deploying Services with Jenkins", outlining the practical path for Kong and Jenkins in enterprise-level continuous delivery. Even with zero prior experience, you can follow the steps to build your own gateway + continuous deployment pipeline. Pre-class Introduction: What is an API Gateway? An API Gateway sits between clients and backend microservices...

    Personal Nov 25, 2025
    28600
  • Nuxt3: Beginner's Guide and Principles Introduction [Learning Notes]

    Nuxt 3: Getting Started and Principles 💡 What is Nuxt 3? Nuxt 3 is a full-stack frontend framework built on Vue 3 and Vite, supporting: Server-Side Rendering (SSR) Static Site Generation (SSG) Single-Page Applications (SPA) Building full-stack applications (with API support) Nuxt 3 is an "enhanced version" of Vue, helping you simplify project structure and development workflow. 🔧 Core Principles Feature How Nuxt Handles It ✅ Page Routing Automatic root...

    Personal Apr 6, 2025
    2.2K00
EN
简体中文 繁體中文 English