深入理解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}` } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypggf.html