写点什么

ES6 新特性详解 - 类

作者:yuanyxh
  • 2024-09-14
    中国香港
  • 本文字数:2252 字

    阅读完需:约 7 分钟

ES6 新特性详解 - 类

简述

文章理解并讲述 ES6 新特性:class。内容有误请指出,内容有缺请补充。


学习 ES6 类之前请先了解 JavaScript 中的 原型与继承ES6 中的类并不是真正意义上的 ,可以理解为对原型与原型继承的一种封装,类模式在 JavaScript 中是一种可选的模式,而不是必须的。

概念

类,在一些面向对象语言中是非常常见的,如 javac++ 等;类可以看作是某一类事物的抽象,泛指一组拥有相同特性相同行为的数据集合,依据某个类接口构造的具体事物称之为该类的实例,是独一无二的个体。


在早期的 JavaScript 中并没有类这样的特性,ES6JavaScript 也拥有了类这样的语法,但 JavaScript 中的类与传统面向对象编程中的类是不同的,其本质还是原型与原型继承。

语法

类可以看作是一个特殊函数,其行为与普通函数并没有太大不同。一个类主要由以下部分组成


  • 构造器

  • 实例方法

  • 静态方法

  • getter、setter 方法

  • 私有、公有字段(实验特性)


这些组成部分都不是必须的,一个空的类声明依旧被 JS 引擎认为是有效的。

类的声明

类使用关键字 class 声明,class 关键字的特性与 let/const 一样


  • 全局作用域下声明的类不会成为 window 的属性

  • 块作用域

  • 同一作用域不能重复声明

  • 没有声明提升


同时,类中的代码都运行在严格模式下,任何严格模式下禁止的操作都会抛出错误


// 类声明class Person {}
// 类表达式const Person = class {};
复制代码

构造器

构造器即 constructor 方法,一般会在该方法内进行初始化操作


class Person {  // 构造器  constructor(name, age) {    // 初始化数据    this.name = name;    this.age = age;  }}
复制代码

实例方法

实例方法,即定义在类原型上的方法,所有当前类的实例都能够访问


class Person {  // 实例方法  sayHi() {    console.log('hi');  }}
const person_1 = new Person();person_1.sayHi(); // hi
const person_2 = new Person();person_2.sayHi(); // hi
复制代码

静态方法

静态方法,即定义在类身上的方法,通过类自身访问,静态方法通过 static 关键字定义


class Person {  // 静态方法  static create() {    return new Person();  }}
const person = Person.create();console.log(person); // {} 空对象
复制代码

getter/setter

即访问器和设置器,用于设置属性访问函数与属性设置函数


class Person {  // 实例属性访问器  get name() {    return this._name;  }  // 实例属性设置器  set name(name) {    this._name = name;  }
// 静态属性访问器 static get name() { return this._name; } // 静态属性设置器 static set name(name) { this._name = name; }}
// 实例属性const p1 = new Person();p1.name = 'yuanyxh';console.log(p1.name); // yuanyxh
// 静态属性Person.name = 'jack';console.log(Person.name); // jack
复制代码

公有、私有字段

类的公有、私有字段定义目前属于实验特性,不应该直接在生产环境中使用,应该使用 babel 之类的编译器编译转换


class Person {  // 公有字段  whoami = 'yuanyxh';
// 私有字段 #whoami = 'yuanyxh';}
复制代码


字段定义所有当前类实例上拥有的数据,公有字段定义允许被外部访问并修改的数据,私有字段定义不应该被外部访问的数据

继承

面向对象编程三大特性其中之一就是继承,继承后的子类能够访问父类的属性,而要在 JavaScript 中实现类的继承,需要使用 extends 关键字,且 extends 不只能继承类,还可以继承函数


// 类class Person {  // 构造器  constructor(name, age) {    // 初始化数据    this.name = name;    this.age = age;  }}
// 子类 继承class Worker extends Person {}
// -----------------------------
// 函数function Person(name, age) { this.name = name; this.age = age;}
// 子类 继承class Worker extends Person {}
复制代码

super

super 关键字用于调用父类构造函数或获取父类数据,具体行为取决于在何处使用,具体规则如下


  • super 在子类构造器中使用时,指向父类构造器,必须在 this 关键词前调用

  • super 在实例方法或实例字段中使用时,指向 父类原型

  • super 在静态方法或静态字段中使用时,指向 父类

  • 通过 super 设置属性时,属性被设置到当前 this 身上

  • super 并不是变量,不能当作变量操作


// 类class Person {  // 构造器  constructor(name, age) {    // 初始化数据    this.name = name;    this.age = age;  }
// 静态方法 static create(...args) { return new Person(...args); }
// 实例方法 sayHi() { console.log('hi'); }}
// 子类 继承class Worker extends Person { constructor(name, age, job) { // 此处 super 引用父类构造器 // 调用父类构造器并传参 super(name, age); this.job = job; }
// 静态方法 static createPerson(...args) { // 此处 super 引用父类本身 return super.create(...args); }
// 实例方法 sayHi() { // 此处 super 引用 父类原型 return super.sayHi(); }}
复制代码


关于 super,虽然它会动态改变引用,但它并不代表 thissuper 永远指向父类或父类原型。


类的其他语法规则可看 MDN#Classes,文章只简要描述。

结语

文章只简要介绍了部分类语法,没有深入探究类的特性,究其原因还是因为 JS 中的类只是语法糖,若想深入了解 JavaScript 中的面向对象编程,还是应该学习并理解原型及原型继承,通过原型与原型继承能够模拟出很多模式,包括类。

参考资料

  • 《JavaScript 高级程序设计》

  • 《你不知道的 JavaScript》

  • MDN


发布于: 刚刚阅读数: 3
用户头像

yuanyxh

关注

站在巨人的肩膀上 2023-08-19 加入

web development

评论

发布
暂无评论
ES6 新特性详解 - 类_js_yuanyxh_InfoQ写作社区