1. ES5中的仿类
ES5中没有类,与类最相近的是创造一个构造器,然后将方法绑定到构造器的原型上,例子如下:
function Person (name) {
this.name = name
}
Person.prototype.getName = function () {
return this.name
}
Person.prototype.setName = function (value) {
this.name = value
}
let person = new Person('zhou') // 创建一个实例
console.log(person.getName()) // zhou
person.setName('jiang')
console.log(person.getName()) // jiang
console.log(person instanceof Person) // true
2. ES6中的类
class Person {
constructor(name) {
this.name = name
}
getName () {
return this.name
}
setName(value){
this.name = value
}
}
let person = new Person('zhou')
console.log(person.getName()) // zhou
person.setName('jiang')
console.log(person.getName()) // jiang
constructor 里面放自有属性,类本质是一个函数
console.log(person instanceof Person) // true
console.log(typeof person) // object
console.log(person instanceof Object) // true
console.log(typeof Person) // function
3. 继承
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
getInfo () {
return `my name is ${this.name}, my age is ${this.age}`
}
setName(name, age){
this.name = name
this.age = age
}
}
// 定义Student集成Person
class Student extends Person {
constructor(name, age) {
super(name, age) // 继承父类的变量 通过super给父类传递参数 name: zhou,age:15
}
}
let student1 = new Student('zhou', 15)
console.log(student1 instanceof Student) // true
console.log(student1 instanceof Person) // true
console.log(student1.getInfo()) // my name is zhou, my age is 15
使用 super() 时需牢记以下几点:
1. 只能在派生类中使用 super() 。若尝试在非派生的类(即:没有使用 extends关键字的类)或函数中使用它,就会抛出错误。
2. 构造器中,你必须在访问 this 之前调用 super() 。由于 super() 负责初始化this ,因此试图先访问 this 自然就会造成错误。
4. 屏蔽派生类中的方法
派生类中的方法总是会屏蔽基类的同名方法,覆盖的意思
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
getInfo () {
return `my name is ${this.name}, my age is ${this.age}`
}
setName(name, age){
this.name = name
this.age = age
}
}
// 定义Student集成Person 派生类
class Student extends Person {
constructor(name, age) {
super(name, age) // 继承父类的变量 通过super给父类传递参数 name: zhou,age:15
}
// 屏蔽父类中的方法
getInfo() {
return this.name
}
}
let student1 = new Student('zhou', 15)
console.log(student1.getInfo()) // zhou
5. 在构造函数中使用 new.target
在简单情况下,new.target 就等于本类的构造器函数
let student = new Student()
new.target 就是 Student 谁new了new.target 就只向谁
class Person {
constructor(name, age) {
console.log(new.target === Person) // false
this.name = name
this.age = age
}
getInfo () {
return `my name is ${this.name}, my age is ${this.age}`
}
setName(name, age){
this.name = name
this.age = age
}
}
// 定义Student集成Person 派生类
class Student extends Person {
constructor(name, age) {
console.log(new.target === Student) // true
super(name, age)
}
// 屏蔽父类中的方法
getInfo() {
return this.name
}
}
let student1 = new Student('zhou', 15)
可以使用 new.target 来创建一个抽象基类(一种不能被实例化的类)
class Person {
constructor(name, age) {
// 抛出错误
if (new.target !== Person) {
throw new Error('err')
}
this.name = name
this.age = age
}
getInfo () {
return `my name is ${this.name}, my age is ${this.age}`
}
setName(name, age){
this.name = name
this.age = age
}
}
// 定义Student集成Person 派生类
class Student extends Person {
constructor(name, age) {
super(name, age)
}
// 屏蔽父类中的方法
getInfo() {
return this.name
}
}
let student1 = new Student('zhou', 15)