描述
在面向对象编程中一个类定义了一个对象的特征. 类是定义 properties
和 一些方法, 是用来绘制具体对象实例的“蓝图”
在 ES6
中 class
本质上就是一个语法糖,使我们编写构造函数更为方便
特性
- 在使用
function
写法时在prototype
上定义方法是默认可枚举的,在使用calss
写法时在prototype
上定义方法是默认不可枚举的 class
也存在暂时性死区的特性- 取值函数和存值函数依然可以使用
- 默认使用严格模式
- 默认会有一个
constructor
不写不会报错 new
方式来执行,不使用new
执行则报错- 内部使用
this
互相调用使用方法和属性
基本写法
class Calculator { // 此时声明了一个构造函数 Calculator
}
声明变量和方法
class Calculator {
// 声明了两个初始变量 num1 和 num2 初始值都为 undefin
num1
num2
// 声明了一个初始变量 action 初始值为 'plus'
action = 'plus'
// 声明方法 plus
plus() {
return this.a + this.b
}
// 声明方法 sub
sub() {
return this.a - this.b
}
// 声明方法 mul
mul() {
return this.a * this.b
}
// 声明方法 div
div() {
return this.a / this.b
}
}
当然,也可以使用变量赋值来声明方法,箭头函数也是可以的
class Foo {
fn = function () { }
arrowFn = () => { }
}
类的初始化 constructor
class Calculator {
num1
num2
// 使用 constructor 来使得 class 被 new 时执行的程序
constructor(num1, num2) {
this.num1 = num1
this.num2 = num2
}
}
静态方法和静态属性
使用 static
关键字来声明 类
内部的静态方法和属性
静态方法和静态属性无法被 实例化对象
调用
class Calculator {
// 声明了一个静态属性 actions 初始值为 ['plus', 'sub', 'mul', 'div']
static actions = ['plus', 'sub', 'mul', 'div']
// 声明了一个静态方法 round
static round(value) {
const type = typeof value
switch (type) {
case 'string':
return Number(value).toFixed(0)
case 'number':
return value.toFixed(0)
default:
return Number(value).toFixed(0)
}
}
}
使用 class
class Calculator {
// 声明了两个初始变量 num1 和 num2 初始值都为 undefin
num1
num2
// 声明了一个初始变量 action 初始值为 'plus'
action = 'plus'
// 声明了一个静态属性 actions 初始值为 ['plus', 'sub', 'mul', 'div']
static actions = ['plus', 'sub', 'mul', 'div']
// 声明了一个静态方法 round
static round(value) {
const type = typeof value
switch (type) {
case 'string':
return Number(value).toFixed(0)
case 'number':
return value.toFixed(0)
default:
return Number(value).toFixed(0)
}
}
// 使用 constructor 来使得 class 被 new 时执行的程序
constructor(num1, num2) {
this.num1 = num1
this.num2 = num2
}
// 声明方法 plus
plus() { return this.num1 + this.num2 }
// 声明方法 sub
sub() { return this.num1 - this.num2 }
// 声明方法 mul
mul() { return this.num1 * this.num2 }
// 声明方法 div
div() { return this.num1 / this.num2 }
run() {
switch (this.action) {
case 'plus':
return this.plus()
case 'sub':
return this.sub();
case 'mul':
return this.mul()
case 'div':
return this.div()
default:
return this.plus()
}
}
}
// 使用 new 关键字来实例化 类(构造函数)
const calculator = new Calculator(5, 10,)
// 调用实例化对象的 run 方法
console.log(calculator.run()) // 15
// 更改实例化对象的 action 属性
calculator.action = 'mul'
// 调用实例化对象的 run 方法
console.log(calculator.run()) // 50
// 更改实例化对象的 action 属性
calculator.action = 'div'
// 调用实例化对象的 div 方法
console.log(calculator.div()) // 0.5
// 调用 类(构造函数) 上的 静态方法 round
console.log(Calculator.round('10.99')) // 11
// 访问 类(构造函数) 上的 静态属性 actions
console.log(Calculator.actions) // ['plus', 'sub', 'mul', 'div']
属性的私有化
用在一些属性成员不想被外部访问的情况
const drink = Symbol()
function study() {
console.log('I am studing');
}
class Person {
// 相对私有化
[drinkAction]() {
console.log('I can drink');
}
// 绝对私有化
study() {
study.call(this)
}
}
访问和赋值的 get
和 set
在 类
中依然可以使用 get
和 set
class Person {
_age = 0
get age() {
return this._age++
}
set age(value) {
if (value > 100) {
console.log("年龄最大不得大于100岁")
return false
}
if (value < 0) {
console.log("年龄最小不得小于0岁")
return
}
this._age = value
}
}
var person = new Person()
console.log(person.age) // 0
console.log(person.age) // 1
person.age = 101 // 年龄最大不得大于100岁
console.log(person.age) // 2
person.age = -1 // 年龄最小不得小于0岁
console.log(person.age) // 3
person.age = 55
console.log(person.age) // 55
extends
extends
是 class
继承的关键字
继承方式相对 function
来讲则要简单的许多,只需要使用 extends
关键即可
class Father {
work() {
console.log('I am working')
}
}
class Son extends Father {
study() {
console.log('I am studing')
}
}
var son = new Son()
son.study() // I am working
son.work() // I am studing
关键字 super
如果在 子类中 使用了 constructor,则必须之中 super 函数,否则会报错
class Parent {
constructor(name = "parent") {
this.name = name
}
}
class Child extends Parent {
// 如果写了 constructor 一定要写 super()
constructor() {
super() // super 不写则报错u
}
new
在使用 class 时,必须通过 new 实例的方式去执行构造函数 否则会报错
const obj = {
}
class Foo {
constructor(name) {
this.name = name
}
}
// 以下几个执行均报错
// Class constructor Foo cannot be invoked without 'new'
Foo('nothing')
Foo.call(obj)
Foo.apply(obj)