一、ES6 类的定义

ES5 构造函数的写法:

function Point(x, y) {
this.x = x;
this.y = y;
}

ES6 引入了 Class(类),通过class关键字,可以定义类。

class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}

这里,ES6 的 Point 类的构造方法对应前面 ES5 的构造函数 Point,代码中的 constructor 是构造方法。

关于 constructor

constructor 是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。

一个类必须有 constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加:

class Point {
} // 等同于
class Point {
constructor() {}
}

二、ES6 类的实例

生成类的实例与 ES5 一样,也是用 new 命令。

但构造函数的实例不用 new 也可以执行,而类必须用 new,否则会报错:

class Point {
// ...
} // 报错
var point = Point(2, 3); // 正确
var point = new Point(2, 3);

三、ES6 类的继承

1、Object.getPrototypeOf()

Object.getPrototypeOf 方法可以用来从子类上获取父类,判断一个类是否继承了另一个类

Object.getPrototypeOf(foo) === Foo
// true

2、extends 关键字实现继承

class Parent{
constructor(lastName='Liu'){
this.lastName=lastName;
}
}
class Child extends Parent{
constructor(lastName){
super(lastName);
}
}
console.log(new Child('Chen')); // 输出结果

3、super 关键字

① super 作为函数调用时,代表父类的构造函数(ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错)

class A {}

class B extends A {
constructor() {
super();
}
}

注意,super 虽然代表了父类 A 的构造函数,但返回的是子类 B 的实例,即 super 内部的 this 指的是 B 的实例,因此 super() 在这里相当于 A.prototype.constructor.call(this)

class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B

上面代码中,new.target 指向当前正在执行的函数。可以看到,在 super() 执行时,它指向的是子类 B 的构造函数,而不是父类 A 的构造函数。也就是说,super() 内部 的 this 指向的是子类 B

②super 作为对象时,在普通方法中指向父类的原型对象;在静态方法中则指向父类

class A {
p() {
return 2;
}
} class B extends A {
constructor() {
super();
console.log(super.p()); //
}
} let b = new B();

上面代码中,子类 B 当中的 super.p(),就是将 super 当作一个对象使用。这时,super 在普通方法之中,指向 A.prototype,所以 super.p() 就相当于 A.prototype.p()

注意,使用 super 的时必须显式指定是作为函数、还是作为对象使用,否则会报错

class A {}

class B extends A {
constructor() {
super();
console.log(super); // 报错
}
}

上面代码中,console.log(super) 当中的 super,无法看出是作为函数使用,还是作为对象使用,所以 JavaScript 引擎解析代码的时候就会报错

四、getter 和 setter

与 ES5 一样,在“类”的内部可以使用 get 和 set 关键字,对某个属性设置取值函数和存值函数,拦截该属性的存取行为

1、getter(取值函数)

class Parent{
constructor(name='Winnie'){
this.name=name;
}
get longName(){
return 'Liu'+this.name;
}
}
let getterName=new Parent();
console.log(getterName.longName);  // LiuWinnie

2、setter(存值函数)

class Parent{
constructor(name='Winnie'){
this.name=name;
}
get longName(){
return 'Liu'+this.name;
}
set longName(value){
this.name=value;
}
}
let setterName=new Parent();
setterName.longName='Honey';
console.log(setterName.longName); // LiuHoney

五、静态方法/属性

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。

但如果在一个方法前加上 static 关键字,则该方法不会被实例继承,而是直接通过类来调用,这种方法称为静态方法。

1、静态方法:使用 static 关键字

class Parent{
static tell(){
console.log('hello');
}
tell(){
console.log('world');
}
}
Parent.tell(); // hello

以上代码还可以看出静态方法可以与非静态方法重名

2、静态属性:直接用 .属性名

class Parent {
} Parent.lastName = 'Liu';
console.log(Parent.lastName); // Liu

上面代码为 Parent 类定义了一个静态属性 lastName

六、name 属性

由于本质上,ES6 的类只是 ES5 的构造函数的一层包装,所以函数的许多特性都被 Class 继承,包括 name 属性

class Point {}
Point.name // "Point"

name 属性总是返回紧跟在 class 关键字后面的类名

let foo = class Foo {
constructor(){
this.name = 'Leo'
}
}
let child = new foo();
console.log(foo.name); // Foo

七、new.target 属性

new 是从构造函数生成实例对象的命令。ES6 为 new 命令引入了一个 new.target 属性,该属性一般用在构造函数之中,返回 new 命令作用于的那个构造函数。如果构造函数不是通过 new 命令或 Reflect.construct() 调用的,new.target 会返回 undefined,因此这个属性可以用来确定构造函数是怎么调用的

function Person(name) {
if (new.target !== undefined) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
} // 另一种写法
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
} var person = new Person('张三'); // 正确
var notAPerson = Person.call(person, '张三'); // 报错

上面代码确保构造函数只能通过 new 命令调用

需要注意的是,子类继承父类时,new.target 会返回子类

ES6 Class(类)的继承与常用方法的更多相关文章

  1. es6 --- class 类的继承使用

    传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...

  2. JS原型,原型链,类,继承,class,extends,由浅到深

    一.构造函数和原型 1.构造函数.静态成员和实例成员 在ES6之前,通常用一种称为构造函数的特殊函数来定义对象及其特征,然后用构造函数来创建对象.像其他面向对象的语言一样,将抽象后的属性和方法封装到对 ...

  3. ES6中的类和继承

    class的写法及继承 JavaScript 语言中,生成实例对象的传统方法是通过构造函数.下面是一个例子     function Point(x, y) {  this.x = x;  this. ...

  4. 【ES6】更易于继承的类语法

    和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态.派生.抽象.迭代.单例等,而且根据 ES6 的新特性衍生出很多有趣的用法. 一.类的基本定义 ...

  5. ES6中。类与继承的方法,以及与ES5中的方法的对比

    // 在ES5中,通常使用构造函数方法去实现类与继承 // 创建父类 function Father(name, age){ this.name = name; this.age = age; } F ...

  6. es6 javascript的Class 类的继承

    原文链接:https://blog.csdn.net/qq_30100043/article/details/53542531 1 基本用法 Class 之间可以通过extends关键字实现继承, 这 ...

  7. ES6——class类继承(读书笔记)

    前言 我一定是一个傻子,昨天这篇文章其实我已经写好了一半了,但是我没有保存 这是学习ES6的过程,我没有系统的看完阮大大的书.零零散散的,很多功能知道,但是没有实际的用过 看了几遍,总是看前面几章,所 ...

  8. ES6学习笔记(二):教你玩转类的继承和类的对象

    继承 程序中的继承: 子类可以继承父类的一些属性和方法 class Father { //父类 constructor () { } money () { console.log(100) } } c ...

  9. ES6 class类 静态方法及类的继承

    一.class类 ES6之前都是定义函数以及函数的原型对象实现类型, 如果想要实现共享构造函数成员,可以用prototype来共享实现 ES6出现之后,使用class类的概念来实现原型的继承 二,静态 ...

随机推荐

  1. 【GStreamer开发】GStreamer基础教程09——收集媒体信息

    目标 有时你需要快速的了解一个文件(或URI)包含的媒体格式或者看看是否支持这种格式.当然你可以创建一个pipeline,设置运行,观察总线上的消息,但GStreamer提供了一个工具可以帮你做这些. ...

  2. 【VS开发】ClientToScreen 和ScreenToClient 用法

    ClientToScreen( )是把窗口坐标转换为屏幕坐标 pWnd->GetWindowRect(&rc);是获取整个窗体的大小pWnd->GetClientRect(& ...

  3. VS混淆/反编译/远程调试/Spy++的Tools工具

    VS的Tools工具(混淆/反编译/远程调试/Spy++等) https://blog.csdn.net/chunyexiyu/article/details/14445605 参考:http://b ...

  4. 利用卷积神经网络处理cifar图像分类

    这是一个图像分类的比赛CIFAR( CIFAR-10 - Object Recognition in Images ) 首先我们需要下载数据文件,地址: http://www.cs.toronto.e ...

  5. python selenium学习

    selenium是一个python模块,具有自动化模拟浏览器的功能 selenium的中文文档地址:http://selenium-python-zh.readthedocs.io/en/latest ...

  6. [转帖]进程上下文频繁切换导致load average过高

    进程上下文频繁切换导致load average过高 2016年6月26日admin发表评论阅读评论 http://www.361way.com/linux-context-switch/5131.ht ...

  7. pycharm 使用black

    pycharm 使用black The Uncompromising Code Formatter By using Black, you agree to cede control over min ...

  8. sublime3 安装markdown插件

    sublime3 安装markdown插件 第一步安装package control 自动安装package control 手动安装package control 安装具体的markdown相关的p ...

  9. hadoop 伪分布启动-fs格式化

    1.独立模式(standalone|local) nothing! 本地文件系统. 不需要启用单独进程. 2.pesudo(伪分布模式) 等同于完全分布式,只有一个节点. SSH: //(Socket ...

  10. Echarts设置y轴值间隔 以及设置 barWidth : 30,//柱图宽度

    需求:如图,y轴之间的距离太小,这样就太过于拥挤了,现在要修改echarts里面的属性,设置y轴值间隔让图表看上去舒服一些.     其实很多问题,真的只是因为自己没有好好的看文档,很多文档上面都写的 ...