ES6类与继承详解:语法、原型链及静态方法

作者:青柠

时间:2026-10-22

浏览:479

本文深入解析ES6中Class与Extends的核心概念。详细阐述类的基本语法、constructor构造方法、super关键字在继承中的作用,以及原生构造函数继承、Generator方法和静态方法的实现机制,帮助开发者清晰理解面向对象编程在ES6中的演进。

文章目录

本文详细解析ES6中类(Class)与继承(Extends)的核心概念及具体用法,旨在为读者提供清晰的参考指南。

类(Class)的基本语法与构造方法

一、类(Class)

1.基本语法

在JavaScript的传统开发模式中,通常通过构造函数来定义并生成新对象。以下是一个传统实现示例:


function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

ES6引入了更接近传统面向对象语言的Class概念,将其作为对象的模板。通过class关键字即可定义类。本质上,ES6的Class可视为语法糖,其大部分功能在ES5中已存在,新写法仅使对象原型的定义更加清晰,更贴合面向对象编程的语法风格。上述传统代码使用ES6类改写后的形式如下:


//定义类
class Point {
  constructor(x, y) {  //constructor 构造方法
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
var p = new Point(1, 2);

在ES6的类定义中,构造函数的prototype属性依然存在。实际上,类的所有方法均定义在类的prototype属性上。

2.constructor方法

constructor是类的默认方法,在使用new命令创建对象实例时会自动调用。每个类都必须包含constructor方法;若未显式定义,系统会自动添加一个空的constructor方法。

继承(Extends)机制与super关键字

二、继承(Extends)

类之间可通过extends关键字实现继承,相比ES5中通过修改原型链实现继承的方式,这种写法更加清晰便捷。


class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }
  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

在上述代码中,constructor方法和toString方法内均出现了super关键字。此处super表示父类的构造函数,用于创建父类的this对象。

子类必须在constructor方法中调用super方法,否则创建实例时会报错。原因是子类自身没有this对象,而是继承父类的this对象并对其进行加工。若不调用super,子类将无法获得this对象。

原生构造函数与Generator方法

三、原生构造函数继承

原生构造函数指语言内置的构造函数,通常用于生成数据结构。ECMAScript的原生构造函数主要包括以下几类:

Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()

ES6允许继承原生构造函数来定义子类,因为ES6的执行机制是先新建父类的实例对象this,再用子类的构造函数修饰this,从而使得父类的所有行为均可被继承。以下是一个继承Array的示例:


class MyArray extends Array {
  constructor(...args) {
    super(...args);
  }
}
var arr = new MyArray();
arr[0] = 12;
arr.length // 1
arr.length = 0;
arr[0] // undefined

上述代码定义了一个MyArray类,该类继承自Array构造函数,因此可以从MyArray生成数组实例。这意味着ES6允许自定义原生数据结构(如Array、String等)的子类,这是ES5所不具备的能力。

四、Class的Generator方法

若在某个方法前添加星号(*),则表明该方法为Generator函数。


class Foo {
  constructor(...args) {
    this.args = args;
  }
  * [Symbol.iterator]() {
    for (let arg of this.args) {
      yield arg;
    }
  }
}
for (let x of new Foo('hello', 'world')) {
  console.log(x);
}
// hello
// world

在上述代码中,Foo类的Symbol.iterator方法前带有星号,表明该方法为Generator函数。Symbol.iterator方法返回Foo类的默认遍历器,for...of循环会自动调用此遍历器。

Class的静态方法

五、Class的静态方法

类相当于实例的原型,类中定义的方法默认会被实例继承。若在方法前添加static关键字,则表明该方法不会被实例继承,而是直接通过类调用,此类方法称为静态方法。


class Foo {
  static classMethod() {
    return 'hello';
  }
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

上述代码中,Foo类的classMethod方法前带有static关键字,表明该方法为静态方法,可直接在Foo类上调用(如Foo.classMethod()),而非在Foo类的实例上调用。若在实例上调用静态方法,将抛出错误,提示该方法不存在。

父类的静态方法可被子类继承。


class Foo {
  static classMethod() {
    return 'hello';
  }
}
class Bar extends Foo {
}
Bar.classMethod(); // 'hello'

上述代码中,父类Foo包含一个静态方法,子类Bar可直接调用该方法。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《ECMAScript6(ES6)入门教程》、《JavaScript数组操作技巧总结》、《JavaScript字符与字符串操作技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript错误与调试技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章