类
类觉不爱【大误】
系列文章
这是JavaScript系列文章:
知识点

类
什么是类?
JavaScript中的类是语法糖,一种基于原型的继承的语法糖。
类有什么作用?
类是面向对象编程的必备条件。
怎么使用类?
使用
new来使用一个之前已经声明好的类。
类里面的方法体不需要添加逗号或者分号隔离
声明
class(类声明)
-
基础语法
// extends是继承的语法,书写后 `子类 extends 父类` class name [extends] { // class body } -
构造函数可选
-
类声明不可以提升
与函数声明不同的是类声明不能提升,所以类声明必须先定义,而函数声明可以先使用再定义。 -
示例一
class Human { constructor(name, weight, height) { this.name = name; this.weight = weight; this.height = height; this.bmi = weight / height / height; } } console.log('bmi: ' + new Human('匿旅', 71, 1.72).bmi); // expected output: bmi: 23.99945916711736 -
示例二
class Human { constructor(weight, height) { this.name = '人类'; this.weight = weight; this.height = height; this.bmi = weight / height / height; } } class Programmer extends Human { constructor(weight, height) { super(weight, height); this.name = '程序员'; } } let iter = new Programmer(71, 1.72); console.log('name: ' + iter.name); // name: 程序员 console.log('bmi: ' + iter.bmi); // bmi: 23.99945916711736 -
注意
- 不要重复声明一个类会报错
class Human { } class Human { } - 类表达式定义一个类后再声明一个类同样会报错
ORlet Human = class { } class Human { }class Human { } let Human = class { } - 报错图示

- 不要重复声明一个类会报错
类表达式
- 基础语法
/** * className 写的话只能在后面的类体内访问到,不写的话就是一个匿名 * exteds 继承父类 * 这个类可以理解为名字为 MyClass */ const MyClass = class [className] [extends] { // class body }; - 示例一:使用类表达式
let World = class { constructor() { } bar () { return 'Hello World!'; } } let instance = new World(); instance.bar(); // "Hello World!" - 示例二:命名类表达式
NamedWorld是不对外的,可以理解为一个私有类名,在外部无法访问,对外访问只能通过World或者new World()使用let World = class NamedWorld { constructor() { } whoIsThere() { return NamedWorld.name; } } let asia = new World(); asia.whoIsThere(); NamedWorld.name; // 会报错 World.name;
class(类声明) 和 类表达式 区别
- 类声明必须有类名,类表达式可以没有类名。
构造方法
-
constructor创建 和 初始化class创建对象的特殊方法,类似JAVA、C#的构造函数,只不过javascript需要借助关键字constructor.
一个类中只能有 一个 构造方法constructor
JavaScript内的构造方法是可选的,可以不写构造函数,这样JavaScript会声明一个默认的构造函数。 -
基础语法
constructor([arguments]) { ... } -
默认构造函数
- 基类构造函数
consturctor() { } - 派生类构造函数
constructor(...args) { super(...args); }
- 基类构造函数
-
示例一
- 问题:如何调用
get和set函数?- get
直接使用实例对象.属性let p = new Parent(); console.log(p.age); - set
直接赋值实例对象.属性 = xxxlet p = new Parent(); p.age = 23;
- get
class Polygon { // ..and an (optional) custom class constructor. If one is // not supplied, a default constructor is used instead: // constructor() { } constructor(height, width) { this.name = 'Polygon'; this.height = height; this.width = width; } } class Square extends Polygon { constructor(length) { // 在这里, 它调用了父类的构造函数, 并将 length 提供给 Polygon 的"width"和"height" super(length, length); // 注意: 在派生类中, 必须先调用 super() 才能使用 "this"。 // 忽略这个,将会导致一个引用错误。 this.name = '正方形'; } get area () { return this.height * this.width; } set area(value) { // 注意:不能使用 this.area = value 为area赋值 // 否则会导致循环call setter方法导致爆栈 this._area = value; } } - 问题:如何调用
-
示例二
polygon
prototypeSquare 类的原型被改变,但是在正在创建一个新的正方形实例时,仍然调用前一个基类 Polygon 的构造函数。
class Polygon { constructor() { this.name = 'Polygon'; } } class Square extends Polygon { constructor() { super(); } } class Rectangle { } Object.setPrototypeOf(Square.prototype, Rectangle.prototype); console.log(Object.getPrototypeOf(Square.prototype) === Polygon.prototype); // false console.log(Object.getPrototypeOf(Square.prototype) === Rectangle.prototype); // true let newInstance = new Square(); console.log(newInstance.name); // Polygon
super
-
简介
- super关键字 至多出现 一次
- 必须在使用
this关键字之前使用 - super关键字 也可以用来调用父对象上的函数。
-
基础语法
// 调用 父对象/父类 构造函数 super([ arguments ]); // 调用 父对象/父类 上的方法 super.functionOfParent([ arguments ]); -
调用父类上的静态方法
class Human { constructor() { } static ping() { return 'ping'; } } class Computer extends Human { constructor() { } static pingpong() { return super.ping() + ' pong'; } } Computer.pingpong(); // "ping pong" -
不能使用
delete删除父类的属性class Base { constructor() { } foo() { } } class Derived extends Base { constructor() { } delete () { delete super.foo; } } new Derived().delete();
extends
-
简介
类声明 和 类表达式 都可以使用 extends ,用来创建一个子类继承另一个类-
还有一段我开始不太懂得话:
- 继承的.prototype必须是一个Object 或者 null。
let Parent = 8; // Number/Boolean/String class Child extends Parent {} // 这里会报错
- 继承的.prototype必须是一个Object 或者 null。
-
-
示例一
继承内置的Date对象class MyDate extends Date { constructor() { super(); } getFormattedDate() { let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; return this.getDate() + "-" + months[this.getMonth()] + "-" + this.getFullYear(); } } -
示例二
class nullExtends extends null { constructor() { } } Object.getPrototypeOf(nullExtends); Object.getPrototypeOf(nullExtends.prototype); new nullExtends();
static

-
简介
- static 关键字声明静态方法
- 不能在类的实例上调用静态方法
- 只能使用类本身调用静态方法
-
基础语法
static methodName() { ... } -
示例一:同一个类中调用其他静态方法
class StaticMethods { static outputLog() { return 'output log'; } static debug() { return this.outputLog() + ' debug'; } } // 使用 StaticMethods.outputLog(); // "output log" StaticMethods.debug(); // "output log debug" -
示例二:在构造函数或者其他方法内调用静态方法
class Parent { constructor() { console.log(Parent.staticMethod()); console.log(this.constructor.staticMethod()); } static staticMethod() { return 'static'; } } new Parent(); // 调用 -
示例三:子类静态方法调用父类静态方法
class Parent { static staticMethod() { return 'parent static'; } } class Child { static staticMethod1() { return super.staticMethod + ' child static'; } } console.log(Parent.staticMethod()); console.log(Child.staticMethod1());
鸣谢
我们之所以看得远,是因为我们站在了巨人的肩膀上。参考列表:



被折叠的 条评论
为什么被折叠?



