深入理解ES6之——JS类的相关知识
基本的类声明
类声明以class关键字开始,其后是类的名称;剩余部分的语法看起来像对象字面量中的方法简写,并且在方法之间不需要使用逗号。
class Person {
    //等价于prototype的构造器
    constructor(name) {
        this.name = name;
    }
    SayName() {
        console.log(this.name);
    }
}
let per = new Person("cf");
per.SayName();//cf
console.log(typeof Person);//function
构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这个对象的实例进行默认的初始化。如果想改变这种默认的初始化,就可以通过自定义构造器来实现。
类与自定义类型的区别
- 类声明不会被提升。类声明的行为类似let,因此在程序的执行到达声明处之前,类会存在于暂时性死区内。
 - 类声明中的所有代码会自动运行在严格模式下,并且也无法退出严格模式
 - 类的所有方法都是不可枚举的
 - 类的所有方法内部都没有[[Construct]],因此使用new来调用他们会抛出错误
 - 调用类构造器时不使用new会抛出错误。
 - 试图在类的内部修改重写类名,会抛出错误。
 
类与函数有相似之处,即它们都有两种形式:声明与表达式
基本的类表达式
let PersonClass = class {
    constructor(name) {
        this.name = name;
    }
    SayName() {
        console.log(this.name);
    }
}
let per = new PersonClass("cc");
per.SayName();
类表达式和类声明都不会被提升
具名类表达式
let PersonClass = class PersonClass2 {
    constructor(name) {
        this.name = name;
    }
    SayName() {
        console.log(this.name);
        console.log(PersonClass2);
    }
}
let per = new PersonClass("cc");
per.SayName();
此例中的类表达式被命名为PersonClass2.PersonClass2只在类定义内部存在,因此只能用在类方法内部。
作为以及公民的类
在编程中,能被当做值来使用的就成为一级公民,意味着他能作为参数,能作为函数返回值,能用来给变量赋值。js的函数就是一级公民。
let createObject = function (classDef) {
    return new classDef();
}
let obj = new createObject(class {
    SayHi() {
        console.log("hi");
    }
})
obj.SayHi();
自有属性需要在类构造器中创建,而类还允许你在原型上定义访问器属性。为了创建一个getter ,要使用 get 关键字,并要与后方标识符之间留出空格;创建 setter 用相同方式,只是要换用 set 关键字
class CustomHtmlElement {
    constructor(element) {
        this.element = element;
    }
    get html() {
        return this.element.innerHTML;
    }
    set html(value) {
        this.element.innerHTML = value;
    }
}
需计算的成员名
类方法与类访问器属性也能使用需计算的名称。语法相同于对象字面量中的需计算名称:无须使用标识符,而是用方括号来包裹一个表达式
let methodName = "SayName";
class PersonClass {
    constructor(name) {
        this.name = name;
    }
    [methodName]() {
        console.log(this.name);
    }
}
let per = new PersonClass("cc");
per.SayName();
生成器方法
可以使用Symbol.iterator来定义生成器方法,从而定义出类的默认迭代器。
class Collection {
    constructor() {
        this.items = [];
    }
    *[Symbol.iterator]() {
        yield this.items;
    }
}
let collection = new Collection();
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for (let num of collection.items) {
    console.log(num);
}
静态成员
静态成员不能通过实例来访问,你始终需要直接用类自身来访问
class PersonClass {
    constructor(name) {
        this.name = name;
    }
    SayName() {
        console.log(this.name);
    }
    static create() {
        return new PersonClass(name);
    }
}
let per = new PersonClass.create("cc");
使用派生类进行继承
class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }
    getArea() {
        return this.length * this.width;
    }
}
class Square extends Rectangle {
    constructor(length) {
        super(length, length);
    }
}
let sq = new Square(10);
console.log(sq.getArea());//100
继承了其他类的类被称为派生类。如果派生类指定了构造器,就需要使用super(),否则就会出错。如果不定义构造器,super()方法会被自动调用,并会使用创建新实例时提供的所有参数。例如:
class Square extends Rectangle {
}
let sq = new Square(10, 10);
console.log(sq.getArea());//100
使用super需要牢记以下几点
- 你只能在派生类中使用super。
 - 在构造器中,你必须在访问this之前调用super()。由于super()负责初始化this,因此试图先访问this自然后报错。
 - 唯一能避免调用super()的办法,是从类构造器中返回一个对象。
 
屏蔽类方法
派生类中的方法总是会屏蔽基类的同名方法。例如:你可以将getArea()方法添加到Square类,以便重新定义它的功能。
class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }
    getArea() {
        return this.length * this.width;
    }
}
class Square extends Rectangle {
    constructor(length, name) {
        super(length, length);
        this.name = name;
    }
    getArea() {
        return `this is ${this.name} input ${this.length}`
    }
}
你也可以使用super.getArea()方法来调用基类中的同名方法
class Square extends Rectangle {
    constructor(length) {
        super(length, length);
    }
    getArea() {
        return super.getArea();
    }
}
继承静态成员
如果基类包含静态成员,那么这些静态成员在派生类中也是可用的。
class Rectangle {
    constructor(length, width) {
        this.length = length;
        this.width = width;
    }
    getArea() {
        return this.length * this.width;
    }
    static create(length, width) {
        return new Rectangle(length, width);
    }
}
class Square extends Rectangle {
    constructor(length) {
        super(length, length);
    }
}
let sqr = Square.create(10, 10);
console.log(sqr.getArea());//100
从表达式中派生类
在ES6中派生类的最强大能力,或许就是能够从表达式中派生类。只要一个表达式能够返回一个具有[[Constructor]]属性以及原型的函数,你就可以对其使用extends。
function Rectangle(length,width){
    this.length = length;
    this.width = width;
}
Rectangle.prototype.getArea = function(){
    return this.length * this.width;
}
class Square extends Rectangle{
    constructor(length){
        super(length,length);
    }
}
let x = new Square(10);
console.log(x.getArea());//100
extends后面能接受任意类型的表达式,这带来了巨大的可能性,例如动态的决定要继承的类。
function Rectangle(length, width) {
    this.length = length;
    this.width = width;
}
Rectangle.prototype.getArea = function () {
    return this.length * this.width;
}
function getBase() {
    return Rectangle;
}
class Square extends getBase() {
    constructor(length) {
        super(length, length);
    }
}
let x = new Square(10);
console.log(x.getArea());
任意表达式都能在extends关键字后使用,但并非所有表达式的结果都是一个有效的类。
- null
 - 生成器函数
 
继承内置对象
在ES6类的继承中,this的值会先被基类创建,随后才被派生类的构造器所修改。结果是this初始就拥有作为基类的内置对象的所有功能,并能正确的接收与之关联的所有功能。
class MyArray extends Array {
}
let arr = new MyArray();
arr[0] = 'red';
console.log(arr.length);
arr.length = 0;
console.log(arr[0]);
Symbol.species属性
继承内置对象的一个有趣方面是:任意能返回内置对象实例的方法,在派生类上却会自动返回派生类的实例。
class MyArray extends Array {
}
let arr = new MyArray(1, 2, 3);
let subitems = arr.slice(1, 2);
console.log(subitems);
												
											深入理解ES6之——JS类的相关知识的更多相关文章
- js作用域的相关知识
		
众所周知,在ES6之前,JavaScript是没有块级作用域的,如下图所示: 学过其他语言的同学肯定有点诧异,为什么会这样呢?因为js还是不同于其他语言的,在ES5中,只有全局作用域和函数作用域,并没 ...
 - js预解析相关知识总结以及一些好玩的面试题
		
js预解析的题像在做智力题一样有意思~ 预解析 预解析:在解释这行代码之前发生的事情——变量的声明提前了,函数的声明提前 console.log(num) ——未定义Num,结果是报错 var num ...
 - python类的相关知识第一部分
		
一.类的相关概念 (1).什么是类 具有同种属性的对象称为类,是个抽象的概念.比如说:汽车.人.狗.神: (2).什么是对象或实例 日常生活中的所有东西都是对象,是类的实例化.比如说:推土车是汽车的实 ...
 - JS的数组相关知识
		
创建数组方法一: var a1=new Array(5); console.log(a1.length); console.log(a1); //[] ,数组是空的 var a2=new Array( ...
 - python类的相关知识第二部分
		
类的继承.多态.封装 一.类的继承 1.应用场景: 类大部分功能相同,大类包含小类的情况 例如: 动物类 共性:都要吃喝拉撒.都有头有脚 特性: 猫类.走了很轻,叫声特别,喜欢白天睡觉 狗类.的叫声很 ...
 - js鼠标事件相关知识
		
1.mousedown->mouseup依次触发后相当于click事件 2.除了mouseenter和mouseleave外,其它的鼠标事件都是冒泡的 3.mouseover和mouseout事 ...
 - Java常用类Date相关知识
		
Date:类 Date 表示特定的瞬间,精确到毫秒. 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年.月.日.小时.分钟和秒值.它也允许格式化和解析日期字符串. Dat ...
 - 【读书笔记】【深入理解ES6】#9-JavaScript中的类
		
大多数面向对象的编程语言都支持类和类继承的特性,而JavaScript却不支持这些特性,只能通过其他方法定义并关联多个相似的对象.这个状态一直从ECMAScript 1持续到ECMAScript 5. ...
 - es6中class类的全方面理解(一)
		
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
 
随机推荐
- C# MessageBox.Show每隔3秒自动关闭
			
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
 - Thrift - 快速入门
			
简单实例 有homebrew的话,直接执行以下命令即可,brew会处理相关依赖(https://thrift.apache.org/docs/install/). brew install thrif ...
 - [oracle 使用(1)] win7/10 下Oracle10g的安装与卸载
			
1.安装前提 首先要确保你的电脑之前没有安装过,或者安装过但是已经卸载干净了.至于如何查看是否卸载干净可以看看我后面的Oracle卸载步骤. 2.Oracle的安装. 2.1.首先自己在Oracle官 ...
 - LeetCode 54. Spiral Matrix(螺旋矩阵)
			
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
 - request的getServletPath(),getContextPath(),getRequestURI(),getRealPath("/")区别
			
假定你的web application 名称为news,你在浏览器中输入请求路径: http://localhost:8080/news/main/list.jsp 则执行下面向行代码后打印出如下结果 ...
 - Python中subplots_adjust函数的说明
			
使用subplots_adjust一般会传入6个参数,我们分别用A,B,C,D,E,F表示.然后我们对图框建立坐标系,将坐标轴原点定在左下角点,并将整个图框归一化,即横纵坐标都是0到1之间.从下图中可 ...
 - linux学习(五)系统目录结构,ls命令,文件类型,alias
			
一.系统目录结构 在我们的根目录下,有这样一些文件夹 /bin /sbin /usr/bin /usr/sbin /sbin一般都是root用户用的 /boot 系统启动相关的,grup就放在这里,这 ...
 - Node.js EventEmitter
			
Node.js EventEmitter Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有 ...
 - Problem A: 求平均年龄
			
Description 定义一个Persons类,用于保存若干个人的姓名(string类型)和年龄(int类型),定义其方法 void addAPerson(string,int) 用于添加1个人的信 ...
 - js实现本地时间同步
			
HTML代码 <html> <head> <title>时间</title> <meta charset="utf-8"> ...