ES6 父子继承中一些执行顺序以及this指向的问题?-灵析社区

办公室高手

有如下代码: class Parent { constructor() { console.log('parent constructor', this.name) this.init() this.logNum = this.logNum.bind(this) } name = (() => { console.log('Parent name init') return 'Parent' })() num = -1 init() { console.log('parent init', this.name) } logNum() {} } class Child extends Parent { constructor() { console.log('Child constructor') super() console.log('super exec finish', this.num) } name = 'Child' num = (() => { console.log('Child num init') return 99 })() init() { console.log('Child init', this.name) super.init() this.num = 10 } logNum() { console.log(this.num) } } const { logNum } = new Child() logNum() 打印结果: Child constructor Parent name init parent constructor Parent Child init Parent parent init Parent Child num init super exec finish 99 99 **1、在实例化Child时,Parent.constructor中的name为什么是'Parent'?** `Child.constructor`中调用`super`,内部`this`指向为`Child`,所以不应该是'Child'吗? **2、诸如x = 'a'的实例属性是什么时候完成初始化的?** `Child.constructor`中调用`super`时,可以看到打印了`'Parent name init'`,说明实例属性是在构造器方法之前就初始化了吧,那为什么`Child.num`是在`super`调用结束后才初始化?

阅读量:14

点赞量:0

问AI
第一问 当实例化Child时,会首先执行父类Parent的构造函数,然后再执行子类Child的构造函数。 在Parent.constructor方法中打断点如下图所示: "image.png" (https://wmlx-new-image.oss-cn-shanghai.aliyuncs.com/images/20241023/69c0d4b14ee9efcaf5e3ec6f546fa87b.png) 从上图Scope栏中的Local作用域可知,虽然this值指向Child,但是其内部的name属性值是“Parent” * 原因是类字段初始化发生在构造函数执行之前。当 Parent 的构造函数被调用时,类字段的初始化,也就是表达式赋值name = (() => { console.log('Parent name init') return 'Parent' })() 已经发生了。 * 虽然this 引用的是 Child 的实例,但是因为表达式赋值是Parent 的构造函数被调用之前执行的,所以 this.name 实际上是在 Child 的实例上设置了一个名为 name 的属性,并赋值为 'Parent'。 * 不妨在Parent中增加如下代码:parentName = "parentName" init() { console.log('parent init', this.name) //结果输出parent init Parent console.log("test: ", this.parentName) //结果输出test: parentName } 实际上还是先对类字段进行初始化,然后再调用构造函数实例化 第二问 当执行 super() 方法时,父类 Parent 的构造函数会执行并初始化父类的实例属性,然后才会继续执行子类 Child 的构造函数。在子类的构造函数中,才会对子类的实例属性比如child.num进行初始化