务必记住这一条【和kotlin的初始化机制是一样的】:
声明可选变量【不会立即赋默认值undefined,必须等到读取时【如没有显示赋值初始值时,才会默认赋值undefined】
public name?: string
推荐使用Test00的方式初始化【清晰执行的先后顺序】
class Test {
public name?: string
constructor() {
console.log("Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined===", this.name)
this.name = "Test"
console.log("Test==Parent==", this.name)
}
a() {
/**
* 优先使用继承子类的name【如没有才使用父类的name】
*/
console.log(`${this.constructor.name}==a==,`, this.name)
}
}
/**
* 推荐初始化方式
*/
class Test00 extends Test {
constructor(_name?: string) {
super()
console.log("Test00【读取父类的name【因为子类没有name属性】==", this.name) // 读取父类的name【因为子类没有name属性
}
}
/**
* 不推荐初始化方式【重复声明不显示初始化的结果和Test00一致】
*/
class Test01 extends Test {
// 声明可选变量【不会立即赋默认值undefined,必须等到读取时【如没有显示赋值初始值时,才会默认赋值undefined】
public name?: string
constructor(_name?: string) {
super()
console.log("Test01【读取父类的name【因为子类name还没有初始化】==", this.name) // 读取父类的name【因为子类name还没有初始化】
}
}
/**
* 不推荐初始化方式【等价于Test02_1】
*/
class Test02 extends Test {
// 声明可选变量【不会立即赋默认值undefined,必须等到读取时【如没有显示赋值初始值时,才会默认赋值undefined】
public name?: string = "Test02"
constructor(_name?: string) {
super() // 不管父类的name为多少,后续优先访问子类的!
console.log("Test02【覆盖父类的name】==", this.name) // 覆盖父类的name
}
}
class Test02_1 extends Test {
// 声明可选变量【不会立即赋默认值undefined,必须等到读取时【如没有显示赋值初始值时,才会默认赋值undefined】
public name?: string
constructor(_name?: string) {
super() // 不管父类的name为多少,后续优先访问子类的!
this.name = "Test02"
this.name = _name
console.log("Test02【覆盖父类的name】==", this.name) // 覆盖父类的name
}
}
/**
* 不推荐初始化方式【等价于Test03_1】
*/
class Test03 extends Test {
// 【不推荐使用】创建实例时自动显示初始化【会强制性立即初始化】
constructor(public name?: string) {
super() // 不管父类的name为多少,后续优先访问子类的!
console.log("Test03【覆盖父类的name】==", this.name) // 覆盖父类的name
}
}
class Test03_1 extends Test {
public name?: string
// 【不推荐使用】创建实例时自动显示初始化【会强制性立即初始化】
constructor(name?: string) {
super() // 不管父类的name为多少,后续优先访问子类的!
this.name = name
console.log("Test03_1【覆盖父类的name】==", this.name) // 覆盖父类的name
}
}
new Test00().a()
console.log("--------------")
new Test01().a()
console.log("--------------")
new Test02().a()
console.log("--------------")
new Test02_1().a()
console.log("--------------")
new Test03().a()
console.log("--------------")
new Test03_1("Test03").a()
// 输出结果为:
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test00【读取父类的name【因为子类没有name属性】== Test
// Test00==a==, Test
// --------------
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test01【读取父类的name【因为子类name还没有初始化】== Test
// Test01==a==, Test
// --------------
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test02【覆盖父类的name】== Test02
// Test02==a==, Test02
// --------------
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test02【覆盖父类的name】== undefined
// Test02_1==a==, undefined
// --------------
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test03【覆盖父类的name】== undefined
// Test03==a==, undefined
// --------------
// Test==Parent==声明后第一次读取【没有赋初始值】默认值为undefined=== undefined
// Test==Parent== Test
// Test03_1【覆盖父类的name】== Test03
// Test03_1==a==, Test03