几个简单的例子学会 ES6 class
「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
是什么
class
是 ES6
中的一个语法糖结构,底层依然是基于原型和构造函数。何以见得呢?
function Person1(name, age) {
this.name = name
this.age = age
}
Person1.prototype.say = function () {
console.log(`My name is ${this.name},i am ${this.age} years old.`)
}
class Person2 {
constructor(name, age) {
this.name = name
this.age = age
}
say() {
console.log(`My name is ${this.name},i am ${this.age} years old.`)
}
}
const xiaoming = new Person1('小明', 18),
xiaohong = new Person2('小红', 20)
console.dir(xiaoming)
xiaoming.say()
console.dir(xiaohong)
xiaohong.say()
可以看到,两个实例的打印结果基本一致,都有原型,原型中都有构造函数,而且两种写法的 say
都是保存在构造函数的原型上。
而且两者都用 new
操作符进行实例化。
而且此时打印 typeof Person2
的结果是 function
。😏
基本使用
class Person {
constructor(name = 'person', age = 18) {
this.name = name
this.age = age
}
say() {
console.log(`My name is ${this.name},i am ${this.age} years old.`)
}
}
const person = new Person(),
xiaoming = new Person('小明', 20)
console.dir(person)
person.say()
console.dir(xiaoming)
xiaoming.say()
可以看到,使用 new
操作符实例化 Person
类的时候传入的参数会被 constructor
接收并使用,如果不需要传入参数,()
可以不写。
static 静态类
假如我们有这样一个场景,要批量生成学生实例,我们可以这样编写 class 类:
class Student {
constructor(name, age) {
this.name = name
this.age = age
this.school = 'JavaScript 小学'
}
say() {
console.log(`My name is ${this.name},i am ${this.age} years old,my school is ${this.school}.`)
}
}
const xiaoming = new Student('小明', 18)
xiaoming.say() // My name is 小明,i am 18 years old,my school is JavaScript 小学.
但是这样做有一个问题就是 school
是统一的,没有必要在每个实例上保存,造成内存浪费,也不利于维护。
这个时候我们就可以改写代码如下:
class Student {
constructor(name, age) {
this.name = name
this.age = age
}
static school = 'JavaScript 小学'
say() {
console.log(this)
console.log(`My name is ${this.name},i am ${this.age} years old,my school is ${Student.school}.`)
}
}
const xiaoming = new Student('小明', 18)
xiaoming.say() // My name is 小明,i am 18 years old,my school is JavaScript 小学.
static
的作用在于:
如果不添加 static
,则属性会被保存在实例上,方法保存在类的原型对象上。
添加 static
后,定义的属性和方法都会绑定在 class 类
上的,所以我们可以通过 Student.school
获取和修改 school
的值。
继承
假设我们的学生中有一些同学是短跑运动员,则他们会有相应的技能。 这个时候我们定义运动员类,而运动员同时又是学生,这个时候就可以让运动员类继承学生类,得到学生相应的属性和方法,同时在运动员类中添加运动员应有的属性和方法。 这个时候我们可以改写代码如下:
class Student {
constructor(name, age) {
this.name = name
this.age = age
}
static school = 'JavaScript 小学'
say() {
console.log(`My name is ${this.name},i am ${this.age} years old,my school is ${Student.school}.`)
}
}
// 使用 extends 关键字继承父类
class Athlete extends Student {
constructor(name, age) {
// 调用父类的 constructor
super(name, age)
}
run() {
console.log(`I am ${this.name},i am running fast!`)
}
}
const xiaoming = new Athlete('小明', 18)
xiaoming.say() // My name is 小明,i am 18 years old,my school is JavaScript 小学.
xiaoming.run() // I am 小明,i am running fast!
这里要注意的是 super
不能脱离 extends
单独使用,但是子类中可以不调用 super()
。
还要注意的是不能在 super()
之前使用 this
,也就是如果子类要使用 this
,则必须调用 super()
。
如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻
转载自:https://juejin.cn/post/7063251767290658829