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
上一篇 Mar 8, 2025 12:52
下一篇 Mar 8, 2025 12:51

Related Posts

  • Go Engineer System Course 010 [Study Notes]

    Install Elasticsearch (understand as a database) and Kibana (understand as a connection tool). The versions of ES and Kibana (port 5601) must be consistent.

    Learning Elasticsearch (ES) by comparison with MySQL: Terminology Mapping
    MySQL | Elasticsearch
    database | index (索引)
    table | type (fixed as _doc from 7.x, multiple types completely removed in 8.x...)

    Personal Nov 25, 2025
    32400
  • 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
    1.8K00
  • Node In-depth and Easy to Understand (Sheng Siyuan Education) 002 [Study Notes]

    Node's package management and loading mechanisms: npm search xxx, npm view xxx, npm install xxx. Node.js file system operation APIs: Node.js's `fs` module provides synchronous (Sync) and callback/Promise-based asynchronous APIs for operating on local files and directories. Commonly used capabilities in daily development include reading, writing, appending, deleting, traversing directories, listening for changes, and so on. The following examples are based on C...

    Personal Nov 24, 2025
    23100
  • Waving to the world, embracing infinite possibilities 🌍✨

    Standing higher, seeing further. Life is like a series of tall buildings; we constantly climb upwards, not to show off the height, but to see a broader landscape. The two girls in the picture stand atop the city, with outstretched arms, as if embracing the boundless possibilities of the world. This is not merely a journey overlooking the city, but rather, a tribute to freedom and dreams. Brave Exploration, Breaking Boundaries. Everyone's life is an adventure; we are born free, and thus should explore unknown landscapes and experience more stories. Perhaps there will be challenges along the way, but it is precisely those moments of ascent...

    Personal Feb 26, 2025
    1.3K00
  • Go Engineering Systematic Course 003 [Study Notes]

    grpc grpc grpc-go grpc seamlessly integrates protobuf protobuf. For those of you accustomed to using JSON and XML data storage formats, I believe most have never heard of Protocol Buffer. Protocol Buffer is actually a lightweight & efficient structured data storage format developed by Google, and its performance is truly much, much stronger than JSON and XML! protobuf…

    Personal Nov 25, 2025
    18800
EN
简体中文 繁體中文 English
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹