【HarmonyOS鸿蒙应用开发者高级认证单题精讲】从桌面冷启动如下应用代码,点击Change按钮5次,整个过程中,代码中的2条log依次出现的次数是
原题: 从桌面冷启动如下应用代码,点击Change按钮5次,整个过程中,代码中的2条log依次出现的次数是
class Data {num: numbertype: stringconstructor(num: number, type: string) {this.num = num;this.type = type;}
}@Reusable
@Component
struct Item {@State data: Data | undefined = undefined;aboutToAppear(): void {console.log("Demo log1");}aboutToReuse(params: ESObject): void {console.log("Demo log2");this.data = params.data}build() {Text("num = " + this.data?.num + ", type = " + this.data?.type)}
}@Entry
@Component
struct Index {data1: Data = new Data(1, "type1");data2: Data = new Data(2, "type2");@State data: Data = this.data1;build() {Column() {if (this.data.type == "type1") {Item({ data: this.data}).reuseId(this.data.type)} else {Item({ data: this.data}).reuseId(this.data.type)}Button('Change').onClick(() => {if (this.data === this.data1) {this.data = this.data2} else {this.data = this.data1}})}}
}
A.2,4
B.6,0
C.1,0
D.1,5
答案:C
解析:
经过仔细研究发现,本题有很多可考察的点,但是似乎本题只考察了一个比较奇怪的点即this.data === this.data1
按照js/ts的逻辑这个比较应该会返回true,接着渲染组件触发aboutToAppear
,然后连续点击Change按钮,因为2号组件被渲染出来,会先触发一次aboutToAppear
,然后因为Item组件被@Reusable
修饰,且设置了reuseId
,以及此时1号组件和2号组件均已在缓存区中,所以接着触发四次aboutToReuse
,所以似乎应该是两条log分别2次和4次。
但是离谱的是this.data === this.data1
并不返回true,后续经过测验,设置不带@State的data3: Data = this.data1
,用data3和data1比较,发现返回true,所以猜测@State修饰的变量并不指向对象的引用,而是进行了深拷贝。
所以this.data === this.data1
这条跑不通,data就一直是1号组件,只会触发一次aboutToAppear
,不论你点击多少次都不变。所以应该各触发1次和0次
PS:
reuseId:复用标识,用于划分自定义组件的复用组。如果不写这个标识,则用组件名来作为标识,即Item,就会混淆1号2号组件
aboutToAppear:aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。
aboutToReuse:当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发aboutToReuse生命周期回调,并将组件的构造参数传递给aboutToReuse。