Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >小结ES6基本知识点(三):类与继承

小结ES6基本知识点(三):类与继承

原创
作者头像
前端林子
修改于 2019-03-09 09:47:53
修改于 2019-03-09 09:47:53
2.3K10
代码可运行
举报
文章被收录于专栏:前端技术总结前端技术总结
运行总次数:0
代码可运行

0,本文适合人群和主要内容

ES6初学者,通过阅读本文可对ES6知识点有个大体的概念,强烈建议阅读阮一峰大大的ES6入门。

老司机可以直接绕路。

上一节主要是总结了Symbol、Set和Map的有关内容。本节要总结ES6中的类、类的继承的有关内容。

1,类

ES5中没有类的概念,只能通过构造函数来初始化对象实例。ES6中可以通过class关键字来定义类。

ES5实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Person(name){
    this.name = name;
}
Person.prototype.hello = function(){
    console.log('Hi',this.name)
}
var person1 = new Person('Peter');
person1.hello(); // Hi Peter
console.log(person1 instanceof Person) // true
console.log(person1 instanceof Object) // true

说明:

先创建一个构造函数Person,然后定义一个方法hello,并赋值给这个构造函数的原型。这样构造函数的所有实例都将共享这个方法。再通过new操作符得到一个实例person1,该实例可以调用hello方法。并且通过instanceof可以看出:该实例person1是构造函数Person的实例、也是对象Object的实例。

ES6实现

通过class关键字声明一个类,上述代码的ES6等价版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person{
    constructor(name){
        this.name = name
    }
    hello(){
        console.log('Hi',this.name)
    }
}
person1 = new Person('Peter');
person1.hello(); // Hi Peter
console.log(person1 instanceof Person) // true
console.log(person1 instanceof Object) // true

说明:

在定义Person类中,先定义constructor方法,这个方法等价于定义Person构造函数。然后在类中直接定义hello方法,这等价于往构造函数的原型上添加方法,即hello方法是添加到Person.prototype属性上。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    // 等价于定义Person构造函数
    constructor(name) {
        this.name = name
    }
    // 等价于Person.prototype.hello
    hello() {
        console.log('Hi', this.name)
    }
}
person1 = new Person('Peter');
person1.hello(); // Hi Peter

几点要注意的地方

(1)ES6中的类是语法糖,本质还是函数,一个具有构造函数方法行为的函数;

例如上述例子中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 console.log(typeof Person) // function

(2)类中通过constructor方法来定义构造函数,在用new关键字初始化实例时自动执行。并且,一个类必须显示定义constructor方法,如果没有,则会默认添加一个空的constructor方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person{
    // 没有定义constructor方法
}

// 等价于

class Person{
    constructor(){}
}

(3)类声明不能被提升,就像let声明不能被提升;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Uncaught ReferenceError: Person is not defined
let person1 = new Person('Peter');
class Person {
    constructor(name) {
        this.name = name;
    }
    hello() {
        console.log('Hi', this.name)
    }
} 

(4)类中定义方法时,不需要function关键字,写法是:方法名(){xxx}这种形式;并且各方法之间不要逗号分隔;

(5)类的名称只在类中为常量,因此在定义类的方法中是不能修改类的名称的,不过可以在声明类之后修改;

内部修改类名会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person{
    constructor(){
        Person = "OterPerson"
    }
}
let person2 = new Person(); // Uncaught TypeError: Assignment to constant variable.

(6)类中的所有方法都是添加到类的原型上,即类的prototype属性上,并且都是不可枚举的,可以通过Object.keys()查看;

验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    constructor(name) {
        this.name = name
    }
    hello() {
        console.log('Hi', this.name)
    }
}
console.log(Person.prototype);
console.log(Object.keys(Person.prototype)); // []
console.log(Object.getOwnPropertyNames(Person.prototype)); // ["constructor", "hello"]

补充:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object.keys(obj) 

返回给定对象obj的所有可枚举属性的字符串数组

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object.getOwnPropertyNames(obj)

返回给定对象obj的所有属性的字符串数组

(7)调用类的构造函数,要通过new调用,不用new则会报错

验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    constructor(name) {
        this.name = name;
    }
    hello() {
        console.log('Hi', this.name)
    }
}
let person1 = Person('Peter'); // Uncaught TypeError: Class constructor Person cannot be invoked without 'new'

(8)类的name属性,就是class关键字后面的标识符。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    constructor(name) {
        this.name = name;
    }
    hello() {
        console.log('Hi', this.name)
    }
}
console.log(Person.name) // Person

(9)new.target

在类的构造函数中使用new.target,一般情况下,new.target等于类的构造函数

验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {    
    constructor(name) {
        this.name = name;
        console.log(new.target === Person)
    }
    hello() {
        console.log('Hi', this.name)
    }
}
let person1 = new Person('Peter') // true

2,继承

引用:

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

ES5实现继承

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Parent(value) {
    this.value = value;
}
Parent.prototype.printValue = function () {
    return this.value
}
function Child(value) {
    Parent.call(this, value);
}
Child.prototype = Object.create(Parent.prototype, {
    constructor: {
        value: Child,
        enumerable: false,
        writable: true,
        configurable: true
    }
});
var child1 = new Child('Peter');
console.log(child1)
console.log(child1.printValue()); // Peter
console.log(child1 instanceof Child); // true
console.log(child1 instanceof Parent); // true

说明:

要Child继承Parent,就用一个从Parent.prototype创建的新对象重写Child的原型child.prototype,并且调用Parent.call()方法,child1:

ES6实现继承

使用extends关键字实现继承,通过调用super()可以访问基类的构造函数

上述代码的ES6等价版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Parent {
    constructor(value) {
        this.value = value;
    }
    printValue() {
        return this.value
    }
}
class Child extends Parent {
    constructor(value) {
        // 等价于 Parent.call(this,value)
        super(value)
        this.value = value
    }
}
let child1 = new Child('Peter');
console.log(child1.printValue()); // Peter
console.log(child1 instanceof Child) // true 
console.log(child1 instanceof Child) // true

几点要注意的地方

(1)使用extends关键字即可实现继承,更符合面向对象的编程语言的写法

(2)关于super():

--只可以在子类的构造函数中使用super,其他地方使用会报错;

验证,在非子类中使用super(),会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Uncaught SyntaxError: 'super' keyword unexpected here
class Parent {
    constructor(value) {
        super(value);
        this.value = value;
    }
    printValue() {
        return this.value
    }
}

--在子类中指定了构造函数则必须调用super(),否则会报错。因为super负责初始化this,如果在调用super()前使用this,则会报错;

验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
class Parent {
    constructor(value) {
        this.value = value;
    }
    printValue() {
        return this.value
    }
}
class Child extends Parent {
    constructor(value) {
        this.value = value
    }
}
let child1 = new Child('Peter');

--如果子类中没定义构造函数,则创建子类实例时,会自动调用super(),并且传入所有参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Child extends Parent {
    // 没有构造函数
}

// 等价于

class Child extends Parent {
    constructor(...args) {
        super(...args)
    }
}

(3)子类也会继承父类的静态方法(static)

(4)关于new.target

如果是子类继承了父类,则父类中的new.target是子类的构造函数:

验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 定义父类
class Rectangle{
    constructor(length,width){
        console.log(new.target === Rectangle) // false
        console.log(new.target === Square) // true
        this.length = length;
        this.width = width;
    }
}
// 定义子类
class Square extends Rectangle{
    constructor(length){
        super(length,length);
    }
}
let square1 = new Square(5); 

3,小结

本文主要通过对比ES5的实现方法,分别总结了ES6中类和类的继承的有关基本知识。如有问题,欢迎指正。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
加油^0^~
加油^0^~
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
小结ES6基本知识点(五):对象的扩展
ES6初学者,通过阅读本文可对ES6知识点有个大体的概念,强烈建议阅读阮一峰大大的ES6入门
前端林子
2019/03/23
2.4K0
小结ES6基本知识点(五):对象的扩展
ES6新特性实现面向对象编程,上万字详解用class语法定义类
首先,写这篇文章是因为我答应了一个粉丝要写一篇ES6的 class 相关知识的要求,哈哈我是不是特别宠粉呀~其实同时也是帮助我自己复习一下知识点啦
@零一
2021/01/29
8751
玩转ES6(四)Set、Map、Class类和decorator 装饰器
在看Class之前建议看一下js的面向对象 https://juejin.im/post/5b8a8724f265da435450c591
前端迷
2019/12/03
8750
详解ES6中的class
class是一个语法糖,其底层还是通过 构造函数 去创建的。所以它的绝大部分功能,ES5 都可以做到。新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
木子星兮
2020/07/16
5210
【THE LAST TIME】一文吃透所有JS原型相关知识点
首先我想说,【THE LAST TIME】系列的的内容,向来都是包括但不限于标题的范围。
Nealyang
2019/11/04
1.1K0
JavaScript的几种继承方式
这篇文章称为笔记更为合适一些,内容来源于 《JavaScript高级程序设计 (第三版)》第六章 6.3 继承。
木子星兮
2020/07/16
5370
原型式继承和类式继承
Java和JavaScript都是面向对象的语言,但二者的继承方式截然不同。前者采用类式继承(classical inheritence),也是大多数面向对象语言的继承方式。而后者采用原型式继承(prototype ineritence),因此称JavaScript为基于对象更加合适。
Chor
2019/11/07
1.5K0
JS es6的Class类详解
JavaScript 语言中,生成实例对象的传统方法是通过构造函数和原型的组合模式.ES6 提供了更接近传统语言(java)的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
全栈程序员站长
2022/06/28
4.7K0
JS es6的Class类详解
前端开发,必知ES5、ES6的7种继承
众所周知,在ES6之前,前端是不存在类的语法糖,所以不能像其他语言一样用extends关键字就搞定继承关系,需要一些额外的方法来实现继承。下面就介绍一些常用的方法,红宝书已经概括的十分全面了,所以本文基本就是对红宝书继承篇章的笔记和梳理。
青梅煮码
2023/03/13
2590
ES6-标准入门·Class 类
直至 ES6,JavaScript 终于有了“类”的概念,它简化了之前直接操作原型的语法,也是我最喜欢的新特性之一,但此类非彼类,它不同于熟知的如 Java 中的类,它本质上只是一颗语法糖。
数媒派
2022/12/01
2930
ES6——类(Class)
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样。
羊羽shine
2019/07/31
1.1K0
JavaScript实现继承
使用class继承非常简单。子类使用extends关键字表明继承于哪个类,并在子类中调用super(),这相当于使用call()改变this的指向。
不作声
2020/10/30
4200
JavaScript ES5 与 ES6 中的类(Class)详解
在 JavaScript 中,ES5 通过 **构造函数(Constructor)** 和 **原型链(Prototype Chain)** 实现面向对象编程(OOP),而 ES6 引入了 `class` 关键字,提供更清晰、更接近传统面向对象语言的语法。以下是两者的对比与详细说明:
jack.yang
2025/04/05
1350
JavaScript ES5 与 ES6 中的类(Class)详解
JS面试题-JS实现继承的方法(共6种)
① 引用类型的属性被所有实例共享。 ② 在创建 Child 的实例时,不能向Parent传参
用户10106350
2022/10/28
7440
JS面试题-JS实现继承的方法(共6种)
ECMAScript中类与继承详解(Java对比学习)
如果声明一个一个类的时候没有声明构造函数,那么会默认添加一个空的构造函数,构造函数在new实例化一个对象的时候会被调用
coder_koala
2019/07/30
4470
【译】《Understanding ECMAScript6》- 第五章-Class
目录 ES5中的拟Class结构 Class声明 Class表达式 存储器属性 静态成员 派生类 new.target 总结 自JavaScript面世以来,许多开发者疑惑为何JavaScript没有Class。大多数面向对象语言都支持Class以及Class继承,尽管部分开发者认为JavaScript语言并不需要Class,但事实上很多第三方库通过工具方法来模拟Class。 ES6正式引入了Class规范。为了保证JavaScript语言的动态性,ES6的Class规范与其他面向对象语言的Class并不完
寒月十八
2018/01/30
1.1K0
JavaScript中的类(ES5+ES6)
ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。
刘亦枫
2020/03/19
9850
ES6基础-ES6 class
面向对象,即万物皆对象,面向对象是我们做开发一种的方式,开发思维,面向对象的思维中万物皆对象,以人作为例子,它的特性有哪些。比如有姓名,性别,出生年月,身高等,还有人的行为,为吃饭,睡觉。特性和行为组合起来就成为人类,特性和行为都是人都有的,通过这些不同的特性和行为给不同的值,构成不同的人。
达达前端
2019/12/03
7930
ES6基础-ES6 class
前端基础-面向对象核心
但是上面这种使用构造函数获取对象的写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
cwl_java
2020/03/26
3200
一万字ES6的class类,再学不懂,请来找我(语法篇)
上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
coder_koala
2021/11/12
3430
相关推荐
小结ES6基本知识点(五):对象的扩展
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验