iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript面向对象之深入了解ES6的class
  • 666
分享到

JavaScript面向对象之深入了解ES6的class

2024-04-02 19:04:59 666人浏览 薄情痞子
摘要

目录前言1.类的定义2.类的构造函数3.类的实例方法4.类的访问器方法5.类的静态方法6.类的继承6.1.extends关键字6.2.super关键字6.3.继承内置类7.类的混入8

前言

在前面一篇中主要介绍了javascript中使用构造函数+原型链实现继承,从实现的步骤来说还是比较繁琐的。在es6中推出的class的关键字可以直接用来定义类,写法类似与其它的面向对象语言,但是使用class来定义的类其本质上依然是构造函数+原型链的语法糖而已,下面就一起来全面的了解一下class吧。

1.类的定义

class关键字定义类可使用两种方式来定义:

class Person {} // 类声明
const Person = class {} // 类表达式

2.类的构造函数

从上面class定义类可以发现是没有()让我们来传递参数的,当希望在实例化对象的给类传递一些参数,这个时候就可以使用到类的构造函数constructor了。

每个类都可以有一个自己的constructor方法,注意只能有一个,如果有多个会抛出异常;

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  constructor() {}
}

当通过new操作符来操作类时,就会去调用这个类的constructor方法,并返回一个对象(具体new操作符调用函数时的默认操作步骤在上一篇中有说明);

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}

const p = new Person('curry', 30)
console.log(p) // Person { name: 'curry', age: 30 }

3.类的实例方法

在构造函数中实现方法继承是将其放到构造函数的原型上,而在class定义的类中,可直接在类中定义方法,最终class还是会帮我们放到其原型上,供多个实例来使用。

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + 'is eating.')
  }

  running() {
    console.log(this.name + 'is running.')
  }
}

4.类的访问器方法

在使用Object.defineProperty()方法来控制对象的属性时,在其数据属性描述符中可以使用setter和getter函数,在class定义的类中,也是可以使用这两个访问器方法的。

class Person {
  constructor(name, age) {
    this.name = name
    this._age = 30 // 使用_定义的属性表示为私有属性,不可直接访问
  }

  get age() {
    console.log('age被访问')
    return this._age
  }

  set age(newValue) {
    console.log('age被设置')
    this._age = newValue
  }
}

const p = new Person('curry', 30)
console.log(p) // Person { name: 'curry', _age: 30 }
p.age // age被访问
p.age = 24 // age被设置
console.log(p) // Person { name: 'curry', _age: 24 }

5.类的静态方法

什么叫类的静态方法呢?该方法不是供实例对象来使用的,而是直接加在类本身的方法,可以使用类名点出来的方法,可以使用static关键字来定义静态方法。

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  static foo() {
    console.log('我是Person类的方法')
  }
}

Person.foo() // 我是Person类的方法

6.类的继承

6.1.extends关键字

在ES6之前实现继承是不方便的,ES6中增加了extends关键字,可以方便的帮助我们实现类的继承。

实现Student子类继承自Person父类:

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + ' is eating.')
  }
}

class Student extends Person {
  constructor(sno) {
    this.sno = sno
  }

  studying() {
    console.log(this.name + ' is studying.')
  }
}

那么子类如何使用父类的属性和方法呢?

6.2.super关键字

使用super关键字可以在子类构造函数中调用父类的构造函数,但是必须在子类构造函数中使用this或者返回默认对象之前使用super。

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + ' is eating.')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  studying() {
    console.log(this.name + ' is studying.')
  }
}

const stu = new Student('curry', 30, 101111)
console.log(stu) // Student { name: 'curry', age: 30, sno: 101111 }
// 父类的方法可直接调用
stu.eating() // curry is eating.
stu.studying() // curry is studying.

但是super关键字的用途并不仅仅只有这个,super关键字一般可以在三个地方使用:

  • 子类的构造函数中(上面的用法);
  • 实例方法中:子类不仅可以重写父类中的实例方法,还可以通过super关键字复用父类实例方法中的逻辑代码;
class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + ' is eating.')
  }

  parentMethod() {
    console.log('父类逻辑代码1')
    console.log('父类逻辑代码2')
    console.log('父类逻辑代码3')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  // 直接重写父类eating方法
  eating() {
    console.log('Student is eating.')
  }

  // 重写父类的parentMethod方法,并且复用逻辑代码
  parentMethod() {
    // 通过super调用父类方法,实现复用
    super.parentMethod()

    console.log('子类逻辑代码4')
    console.log('子类逻辑代码5')
    console.log('子类逻辑代码6')
  }
}

静态方法中:用法就和实例方法的方式一样了;

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  static parentMethod() {
    console.log('父类逻辑代码1')
    console.log('父类逻辑代码2')
    console.log('父类逻辑代码3')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  // 重写父类的parentMethod静态方法,并且复用逻辑代码
  static parentMethod() {
    // 通过super调用父类静态方法,实现复用
    super.parentMethod()

    console.log('子类逻辑代码4')
    console.log('子类逻辑代码5')
    console.log('子类逻辑代码6')
  }
}

Student.parentMethod()

6.3.继承内置类

extends关键字不仅可以实现继承我们自定义的父类,还可以继承JavaScript提供的内置类,可对内置类的功能进行扩展。

比如,在Array类上扩展两个方法,一个方法获取指定数组的第一个元素,一个方法数组的最后一个元素:

class myArray extends Array {
  firstItem() {
    return this[0]
  }

  lastItem() {
    return this[this.length - 1]
  }
}

const arr = new myArray(1, 2, 3)
console.log(arr) // myArray(3) [ 1, 2, 3 ]
console.log(arr.firstItem()) // 1
console.log(arr.lastItem()) // 3

7.类的混入

何为类的混入?在上面的演示代码中,都只实现了子类继承自一个父类,因为JavaScript的类只支持单继承,不能继承自多个类。如果非要实现继承自多个类呢?那么就可以引入混入(Mixin)的概念了。

看看JavaScript中通过代码如何实现混入效果:

// 封装混入Animal类的函数
function mixinClass(BaseClass) {
  // 返回一个匿名类
  return class extends BaseClass {
    running() {
      console.log('running...')
    }
  }
}

class Person {
  eating() {
    console.log('eating...')
  }
}

class Student extends Person {
  studying() {
    console.log('studying...')
  }
}

const NewStudent = mixinClass(Student)
const stu = new NewStudent
stu.running() // running...
stu.eating() // eating...
stu.studying() // studying...

混入的实现一般不常用,因为参数不太好传递,过于局限,在JavaScript中单继承已经足够用了。

8.class定义类转ES5

上面介绍ES6中类的各种使用方法,极大的方便了我们对类的使用。我们在日常开发中编写的ES6代码都是会被babel解析成ES5代码,为了对低版本浏览器做适配。那么使用ES6编写的类被编译成ES5语法会是什么样呢?通过babel官网的试一试可以清楚的看到ES6语法转成ES5后的样子。

  • 刚开始通过执行自调用函数得到一个Person构造函数;
  • 定义的实例方法和类方法会分别收集到一个数组中,便于后面直接调用函数进行遍历添加;
  • 判断方法类型:如果是实例方法就添加到Person原型上,是类方法直接添加到Person上;
  • 所以class定义类的本质还是通过构造函数+原型链,class就是一种语法糖;

这里可以提出一个小问题:定义在constructor外的属性最终会被添加到哪里呢?还是会被添加到类的实例化对象上,因为ES6对这样定义的属性进行了单独的处理。

class Person {
  message = 'hello world'

  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + ' is eating.')
  }

  static personMethod() {
    console.log('personMethod')
  }
}

const p = new Person('curry', 30)
console.log(p) // Person { message: 'hello world', name: 'curry', age: 30 }

扩展:在上图中通过通过babel转换后的代码中,定义的Person函数前有一个,那么这个有什么作用呢?

  • 实际上这个符号将函数标记为了纯函数,在JavaScript中纯函数的特点就是没有副作用,不依赖于其它东西,独立性很强;
  • 在使用webpack构建的项目中,通过babel转换后的语法更有利于WEBpack进行tree-shaking,没有使用到的纯函数会直接在打包的时候被压缩掉,达到减小包体积效果;

总结

到此这篇关于JavaScript面向对象之深入了解ES6的class的文章就介绍到这了,更多相关了解ES6的class内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript面向对象之深入了解ES6的class

本文链接: https://www.lsjlt.com/news/142993.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript面向对象之深入了解ES6的class
    目录前言1.类的定义2.类的构造函数3.类的实例方法4.类的访问器方法5.类的静态方法6.类的继承6.1.extends关键字6.2.super关键字6.3.继承内置类7.类的混入8...
    99+
    2022-11-13
  • JavaScript面向对象之class继承类案例讲解
    1. 面向对象class继承 在上面的章节中我们看到了JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的类-实例模型要困难,最大的缺点是继承的实现需要...
    99+
    2022-11-12
  • JavaScript的面向对象你了解吗
    目录1. 面向对象编程介绍1.1 两大编程思想1.2 面向过程编程 POP(Process - oriented - programming)1.3 面向对象编程 OOP(Objec...
    99+
    2022-11-13
  • 【Java 基础篇】Java反射:深入了解Class对象
    Java是一门强类型语言,它要求在编译时知道所有的类和对象类型。然而,有时候我们需要在运行时动态地获取和操作类的信息,这就是Java反射的用武之地。本文将深入探讨Java反射,特别是与Class对象...
    99+
    2023-10-27
    java python 开发语言 ajax 网络 eclipse git 原力计划
  • Java 深入浅出解析面向对象之抽象类和接口
    目录抽象类声明抽象类声明抽象方法案例使用规则接口声明接口案例接口特性抽象类和接口的区别抽象类 java语言,声明类时 abstract class Db{} 说明Db类为抽象类。 j...
    99+
    2022-11-13
  • C++深入讲解类与对象之OOP面向对象编程与封装
    目录1.面向对象编程2.面向过程性编程和面向对象编程3.类的引入4.类的定义4.1类的两种定义方式4.1.1声明和定义全部放在类体中4.2.2.声明和定义不放在类体中5.类的访问限定...
    99+
    2022-11-13
  • 一起来了解JavaScript面向对象
    目录JavaScript原型链Object的原型顶层原型创建Object对象的内存图Object是所有类的父类原型链实现继承借用构造函数实现继承总结JavaScript原型链 每一个...
    99+
    2022-11-12
  • 深入浅析java中的面向对象
    本篇文章给大家分享的是有关深入浅析java中的面向对象,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一.面向对象(OO)面向对象(OO):就是基于对象概念,以对象为中心,以类和...
    99+
    2023-05-31
    面向对象 java ava
  • 详解JavaScript面向对象实战之封装拖拽对象
    目录概述1、如何让一个DOM元素动起来2、如何获取当前浏览器支持的transform兼容写法3、如何获取元素的初始位置5、我们需要用到哪些事件?6、拖拽的原理7、我又来推荐思维导图辅...
    99+
    2022-11-12
  • 深入了解java中的string对象
    这里来对Java中的String对象做一个稍微深入的了解。Java对象实现的演进String对象是Java中使用最频繁的对象之一,所以Java开发者们也在不断地对String对象的实现进行优化,以便提升String对象的性能。(推荐学习:J...
    99+
    2019-07-17
    java教程 java string
  • JAVA面向对象之继承 super入门解析
    目录1 继承1.1概念1.2 特点1.3 练习:继承入门案例2 super3 继承的用法3.1 练习:super之继承中成员变量使用3.2 练习:super之继承中构造方法的使用4 ...
    99+
    2022-11-13
  • 深入浅析Kotlin中的面向对象编程
    这篇文章给大家介绍深入浅析Kotlin中的面向对象编程,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Kotlin 面向对象可以看到Kotlin中的类还是很普通的,大多与Java相似,比较特殊的有:每一个构造函数都必须为...
    99+
    2023-05-31
    kotlin 面向对象
  • Java面向对象关键字extends继承的深入讲解
    目录一、问题引出二、继承extends2.1继承的用法2.2基本语法2.3继承的好处2.4继承性总结一、 问题引出 面向对象的编程思想使得代码中创建的类更加具体,他们都有各自的属性...
    99+
    2022-11-12
  • 深入了解Java File对象的使用
    目录1.File对象 2.创建文件3.文件的相关操作1.File对象  java封装的一个操作文件及文件夹(目录)的对象。可以操作磁盘上的任何一个文件和文件夹。 2.创建文件 方式一...
    99+
    2022-11-13
    Java File对象 Java File
  • Python面向对象编程之区间的插入详解
    目录一、面向对象编程的Python实例描述二、面向对象编程的Python实例的示例三、面向对象编程的Python实例的编写过程3.1 本文的集成编译环境3.2 编写Interval类...
    99+
    2022-11-11
  • 深入了解php对象中的“->”符号
    PHP是一种非常流行的编程语言,它是一种服务器端脚本语言,被广泛用于Web编程领域。在PHP编程中,经常会用到对象及其属性和方法。在PHP中,通过“->”符号可以访问对象的属性和方法。不过在理解的时候需要先明白什么是对象。对象是指现实...
    99+
    2023-05-14
  • JavaScript面向对象中的封装和继承你了解吗
    目录1、面向对象1、封装2、原型对象3、继承总结1、面向对象 【三大显著特征】: 封装、继承、多态 1、封装 【解释】: 封装的本质就是将有关联的代码组合在一起。...
    99+
    2022-11-13
  • Javascript基之js面向对象的示例分析
    这篇文章主要为大家展示了“Javascript基之js面向对象的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Javascript基之js面向对象的示例...
    99+
    2022-10-19
  • Python面向对象编程之封装的艺术你了解吗
    目录1.面向对象编程 1.1OOP特点1.2OOP基本概念2.Python实现OOP2.1分析问题2.2类设计语法2.3创建对象语法3.OOP的封装性3.1广义角度:无处不...
    99+
    2022-11-13
  • C++深入探索类和对象之封装及class与struct的区别
    目录封装的意义访问权限class和struct的区别成员属性私有案例练习封装的意义 封装是C++三大面向对象之一 意义: 1、设计类的时候,属性和行为写在一起,表现事物 2、类在设计...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作