【Javascript】ES6新增之类的认识

news/2024/7/11 1:54:15 标签: javascript, es6, 前端

在现代编程语言中,类是面向对象编程范式中的核心概念之一。
与函数类似,类本质上是一种特殊的函数,它允许我们将数据和操作封装在一起,以创建具有共同行为和状态的对象。
在类的世界里,我们有类表达式和类声明,它们各自具有自己的特性和用途。

✨ 类本质上是一种特殊的函数。所以和函数一样,有类表达式和类声明

类声明

函数不同,类声明不会被提升。这意味着在使用类之前,需要先进行类声明。类声明通常包括构造函数和其他成员方法。构造函数是一个特殊的方法,用于创建和初始化类所创建的对象。

// 类声明
class Rectangle {
  constructor(height, width) {
    this.height = height; // 实例成员
    this.width = width;
  }
}

let p = new Rectangle();

类表达式

  • 类表达式可以命名,也可以不命名
  • 我们可以通过类的name属性来检索
// 未命名/匿名类
let Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name);
// output: "Rectangle"

// 命名类
// 命名类表达式的名称是该类体的局部名称。
let Rectangle = class Rectangle2 {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name);
// 输出:"Rectangle2"

类的定义

  • {}中的部分叫做类体。
  • 类体中会包括:
    • 构造函数

      • constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。
      • 注意⚠️:一个类体中只能有一个constructor方法
      • 使用 super 关键字来调用一个父类的构造函数
    • 原型方法

      class Rectangle {
        // constructor
        constructor(height, width) {
      // 实例的属性必须定义在类的方法里
          this.height = height;
          this.width = width;
        }
        // Getter
        get area() {
          return this.calcArea();
        }
        // Method
        calcArea() {
          return this.height * this.width;
        }
      }
      const square = new Rectangle(10, 10);
      
      console.log(square.area);
      // 100
      
    • 静态方法

      • static来定义静态方法,只能被类访问
      class Point {
        constructor(x, y) {
          this.x = x;
          this.y = y;
        }
      
        static displayName = "Point";
      
        static distance(a, b) {
          const dx = a.x - b.x;
          const dy = a.y - b.y;
          return Math.hypot(dx, dy);
        }
      }
      
      const p1 = new Point(5, 5);
      const p2 = new Point(10, 10);
      p1.displayName;
      // undefined
      p1.distance;
      // undefined
      
      console.log(Point.displayName);
      // "Point"
      console.log(Point.distance(p1, p2));
      // 7.0710678118654755
      
    • getter和setter

  • 类体中遵循严格模式

this指向

类中

  1. 类体中的成员方法遵循严格模式。this在类方法中的行为与传统函数有所不同。在调用静态或原型方法时,this默认指向undefined,但在非严格模式下,会自动装箱以保留传入状态。

  2. 当被调用时。谁调用,指向谁

    class Animal {
    // 原型方法
      speak() {
        return this;
      }
    // 静态方法
      static eat() {
        return this;
      }
    }
    
    let obj = new Animal();
    obj.speak(); // Animal {}
    let speak = obj.speak;
    speak(); // undefined
    
    Animal.eat(); // class Animal
    let eat = Animal.eat;
    eat(); // undefined
    

传统函数中

在非严格模式下调用函数,会发生自动装箱。即如果初始值时undefined,则this指向全局对象。

function Animal() {}

Animal.prototype.speak = function () {
  return this;
};

Animal.eat = function () {
  return this;
};

let obj = new Animal();
let speak = obj.speak;
speak(); // global object

let eat = Animal.eat;
eat(); // global object

字段声明

公有字段

  1. 不需要let, const等关键字
  2. 预先声明
class Rectangle {
  height = 0;
  width;
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

私有字段

  1. 只能在类内部读取,外部无法调用。
  2. 私有字段仅能在字段声明中预先定义。
class Rectangle {
  #height = 0;
  #width;
  constructor(height, width) {
    this.#height = height;
    this.#width = width;
  }
}

extends

我们可以创建一个子类来扩展父类的功能。子类继承了父类的属性和方法,并可以在其基础上进行扩展或重写。

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

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

class Son extends Father {
  constructor(name) {
    super(name); // 调用超类构造函数并传入 name 参数
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}

var d = new Son("Mitzie");
d.speak(); // 'Mitzie barks.'

super

super 关键字用于调用对象的父对象上的函数.

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

  speak() {
    console.log(this.name + " makes a noise.");
  }
}

class Son extends Father {
  speak() {
    super.speak();
    console.log(this.name + " roars.");
  }
}

| 本文参考:MDN


http://www.niftyadmin.cn/n/4936378.html

相关文章

RocketMQ 5.1.0 源码详解 | Producer 发送流程

文章目录 初始化DefaultMQProducer实例发送流程DefaultMQProducer#sendDefaultMQProducerImpl#sendMQClientInstance#updateTopicRouteInfoFromNameServer使用特定 topic 获取路由信息使用默认 topic 获取路由信息 DefaultMQProducerImpl#sendDefaultImpl发送流程总结 初始化De…

【C语言】12-数组之一维数组

0. 什么是数组 在之前的学习中,学习了整型、字符型、浮点型这些数据类型,在面对简单问题时,使用这些简单的数据类型就足够了,但是如果遇到数据量较大的情况,并且需要对数据进行一些处理时,使用以上的数据类型就不是很有效了。例如要对班级 50 名同学的成绩进行排序,假设…

掌握Python的X篇_32_使用python编辑pdf文件_pdfrw

本篇介绍利用python操作pdf文件,我们平时也会有合并和拆分pdf的需求,此时我们就可以使用本节内容。 文章目录 1. pdfrw的安装2. 切分pdf文件3. pdfrw官网及实现一版四面的实例 1. pdfrw的安装 pip install pdfrw官网地址:https://github.co…

Rx.NET in Action 第一章学习笔记

Part 1 初入反应式扩展 什么是反应式程序?它们有什么用?使用反应式扩展(Rx)编程,会如何改变你编写代码的方式?在开始使用 Rx 之前应该做些什么?为什么 Rx 比传统的事件驱动编程更好&#xff1f…

什么是多线程?进程和线程的区别是什么?如何使用Java实现多线程?

文章目录 前言我们为什么要使用线程而不是进程来实现并发编程什么是线程进程和线程的区别如何使用Java实现多线程创建线程1.创建一个继承 Thread 类的线程类2.实现 Runnable 接口匿名内部类方式实现 Runnable 接口lambda 表达式实现 Runnable 接口 Thread 类的常见构造方法Thre…

TypeScript 语法

环境搭建 以javascript为基础构建的语言,一个js的超集,可以在任何支持js的平台中执行,ts扩展了js并且添加了类型,但是ts不能被js解析器直接执行,需要编译器编译为js文件,然后引入到 html 页面使用。 ts增…

系统架构设计专业技能 · 系统安全分析与设计(四)【加解密、数字信封、信息摘要、数字签名、数字书证、网络安全、信息安全】

系列文章目录 系统架构设计专业技能 网络规划与设计(三)【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计(四)【系统架构设计师】 系统架构设计高级技能 软件架构设计(一)【系统架构设计师…

IDEA关闭项目,但是后台程序没有关闭进程(解决方案)

最近遇到一个很奇怪的问题,idea关闭项目后,系统进程没有杀死进程,再次执行的时候会提示端口占用,并提示Process exited with an error: 1 (Exit value: 1) 错误原因:应用程序关闭后,进程不能同步关闭 解决方…