一、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. tp5 关键字模糊查询 日期查询 小于大于某范围等查询的优点

    挺不错,用熟了这tp5封装的很方便. 类似上边一个查询多个操作,基本在model 一个方法搞定代码也不用很多, 首先要学会用scope  网上搜tp scope 有几个例子可以借鉴 model 内添加 ...

  2. URI和URL的关系与区别

    首先给大家举个例子,有一家公司的总经理,某天,给了我一张名片,上面写了他的头衔,北京XXX公司总经理 张三,还有他的办公室地址,北京市海淀区长安街35号北京XXX公司总经理办公室,那么,我以后给我的朋 ...

  3. python 之 网络编程(基于UDP协议的套接字通信)

    8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...

  4. 最简容器动手小实践——FC坦克大战游戏容器化

    FC 经典力作相信大家一点也不陌生.童年时期最频繁的操作莫过于跳关,在 果断跳到最后一关之后,一般都是以惨败告终,所以还是一关一关的过原始积累才能笑到最后.这款游戏的经典就在于双人配合,守家吃装备.也 ...

  5. babel编译ts

    这里用的是babel7 npx babel src --out-dir lib --extensions ".ts"

  6. 起始路由改成分区(Areas)的RouteConfig.cs配置方法

    public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/ ...

  7. springcloud源码解析(目录)

    springcloud是一个基于springboot的一站式企业级分布式应用开发框架.springboot为其提供了创建单一项目的便利性,springcloud组合了现有的.常用的分布式项目的解决方案 ...

  8. 【转载】Sqlserver使用Group By进行分组并计算每个组的数量

    在SQL语句查询中,Group By语句时常用来进行分组操作,有时候在分组的同时还需要计算出每个组的数量多少.在Sqlserver数据库中可以使用Group By加Count聚合函数来实现此功能,即通 ...

  9. echarts3关系图:力引导布局, 固定某些节点

    在数组里设置 fixed: true,<a href='http://echarts.baidu.com/option.html#series-graph.data.fixed'>官方文档 ...

  10. Eclipse 交叉编译环境

    创建空工程 添加交叉编译环境 添加工程文件 如需修改交叉编译环境 Cross GCC:使用交叉编译命令编译,需要自己指定 MinGW GCC:使用make命令编译,需要有Makefile Make T ...