ES6 Class(类)的继承与常用方法
一、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(类)的继承与常用方法的更多相关文章
- es6 --- class 类的继承使用
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- JS原型,原型链,类,继承,class,extends,由浅到深
一.构造函数和原型 1.构造函数.静态成员和实例成员 在ES6之前,通常用一种称为构造函数的特殊函数来定义对象及其特征,然后用构造函数来创建对象.像其他面向对象的语言一样,将抽象后的属性和方法封装到对 ...
- ES6中的类和继承
class的写法及继承 JavaScript 语言中,生成实例对象的传统方法是通过构造函数.下面是一个例子 function Point(x, y) { this.x = x; this. ...
- 【ES6】更易于继承的类语法
和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态.派生.抽象.迭代.单例等,而且根据 ES6 的新特性衍生出很多有趣的用法. 一.类的基本定义 ...
- ES6中。类与继承的方法,以及与ES5中的方法的对比
// 在ES5中,通常使用构造函数方法去实现类与继承 // 创建父类 function Father(name, age){ this.name = name; this.age = age; } F ...
- es6 javascript的Class 类的继承
原文链接:https://blog.csdn.net/qq_30100043/article/details/53542531 1 基本用法 Class 之间可以通过extends关键字实现继承, 这 ...
- ES6——class类继承(读书笔记)
前言 我一定是一个傻子,昨天这篇文章其实我已经写好了一半了,但是我没有保存 这是学习ES6的过程,我没有系统的看完阮大大的书.零零散散的,很多功能知道,但是没有实际的用过 看了几遍,总是看前面几章,所 ...
- ES6学习笔记(二):教你玩转类的继承和类的对象
继承 程序中的继承: 子类可以继承父类的一些属性和方法 class Father { //父类 constructor () { } money () { console.log(100) } } c ...
- ES6 class类 静态方法及类的继承
一.class类 ES6之前都是定义函数以及函数的原型对象实现类型, 如果想要实现共享构造函数成员,可以用prototype来共享实现 ES6出现之后,使用class类的概念来实现原型的继承 二,静态 ...
随机推荐
- tp5 关键字模糊查询 日期查询 小于大于某范围等查询的优点
挺不错,用熟了这tp5封装的很方便. 类似上边一个查询多个操作,基本在model 一个方法搞定代码也不用很多, 首先要学会用scope 网上搜tp scope 有几个例子可以借鉴 model 内添加 ...
- URI和URL的关系与区别
首先给大家举个例子,有一家公司的总经理,某天,给了我一张名片,上面写了他的头衔,北京XXX公司总经理 张三,还有他的办公室地址,北京市海淀区长安街35号北京XXX公司总经理办公室,那么,我以后给我的朋 ...
- python 之 网络编程(基于UDP协议的套接字通信)
8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...
- 最简容器动手小实践——FC坦克大战游戏容器化
FC 经典力作相信大家一点也不陌生.童年时期最频繁的操作莫过于跳关,在 果断跳到最后一关之后,一般都是以惨败告终,所以还是一关一关的过原始积累才能笑到最后.这款游戏的经典就在于双人配合,守家吃装备.也 ...
- babel编译ts
这里用的是babel7 npx babel src --out-dir lib --extensions ".ts"
- 起始路由改成分区(Areas)的RouteConfig.cs配置方法
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/ ...
- springcloud源码解析(目录)
springcloud是一个基于springboot的一站式企业级分布式应用开发框架.springboot为其提供了创建单一项目的便利性,springcloud组合了现有的.常用的分布式项目的解决方案 ...
- 【转载】Sqlserver使用Group By进行分组并计算每个组的数量
在SQL语句查询中,Group By语句时常用来进行分组操作,有时候在分组的同时还需要计算出每个组的数量多少.在Sqlserver数据库中可以使用Group By加Count聚合函数来实现此功能,即通 ...
- echarts3关系图:力引导布局, 固定某些节点
在数组里设置 fixed: true,<a href='http://echarts.baidu.com/option.html#series-graph.data.fixed'>官方文档 ...
- Eclipse 交叉编译环境
创建空工程 添加交叉编译环境 添加工程文件 如需修改交叉编译环境 Cross GCC:使用交叉编译命令编译,需要自己指定 MinGW GCC:使用make命令编译,需要有Makefile Make T ...