先来看看表象,使用不同的定义方式(箭头函数和普通函数)去定义类里面的函数,如果不同的话会产生不同的效果。
/**
* 父类普通函数
* 子类普通函数
*/
class Parent0 {
sayName() {
console.log("我是父类");
}
}
class Child0 extends Parent0 {
sayName() {
console.log("我是子类");
}
}
const c0 = new Child0()
c0.sayName() // 我是子类
/**
* 父类箭头函数
* 子类普通函数
*/
class Parent1 {
sayName = () => {
console.log("我是父类");
}
}
class Child1 extends Parent1 {
sayName() {
console.log("我是子类");
}
}
const c1 = new Child1()
c1.sayName() //我是父类
/**
* 父类箭头函数
* 子类箭头函数
*/
class Parent2 {
sayName = () => {
console.log("我是父类");
}
}
class Child2 extends Parent2 {
sayName = () => {
console.log("我是子类");
}
}
const c2 = new Child2()
c2.sayName() //我是子类
/**
* 父类普通函数
* 子类箭头函数
*/
class Parent3 {
sayName () {
console.log("我是父类");
}
}
class Child3 extends Parent3 {
sayName = () => {
console.log("我是子类");
}
}
const c3 = new Child3()
c3.sayName() //我是子类
为什么会产生第二种情况呢?
这是因为在第二种请况下,父类的方法是使用箭头函数写的,而箭头函数里面含有 = ,这样的话在每一次调用构造函数去创建新的对象时都会在实例里面创建一个单独的 sayName()方法;
而子类里面的方法是写在原型链上的,这样的话每一次创建实例并不会单独创建 sayName()方法,而是会通过原型链去往上找,但是由于父类的sayName()已经被实例创建,因此 并不会访问子类的方法,而是会访问父类。