0
点赞
收藏
分享

微信扫一扫

鸿蒙,ArkTs 一段诡异的代码

hi 大家好,我是 DHL。就职于美团、快手、小米。公众号:ByteCode,分享有用的原创文章,涉及鸿蒙、Android、Java、Kotlin、性能优化、大厂面经。

分享一段我之前在学习 ArkTs 的时候,看到的一段诡异的代码。我们来看看下面的代码,按照你多年的经验,分析一下下面的代码是否可以正常执行,如果可以执行的话,能说出运行结果吗。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}

以上代码是可以正常运行的,这段代码的执行结果,将会输出了 3 个 'abc'

abc
abc
abc

这段代码中的 for 循环尝试执行三次循环,每次循环中都声明了一个新的局部变量 i,并将其赋值为字符串 'abc'。然后,它打印出这个新的局部变量 i

在每次迭代中,尽管外部循环的控制变量也叫 i,但内部的 let i = 'abc'; 实际上创建了一个新的、同名的局部变量 i,这个变量的作用域仅限于 for 循环的块内部。因此,每次迭代打印的都是这个块作用域内的字符串 'abc',而不是外部循环控制变量的数值。

从执行结果也能间接说明,for 循环内部声明的变量 i 和循环变量 i 不在同一个作用域,它们有各自单独的作用域,设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域,这是 for 循环的特别之处。

如果在同一个作用域,是不可使用 let 或者 const 重复声明相同名字的变量。比如下面的代码会报错。

if(true){
    let a = 1;
    let a = 2; // 报错
    
    const b = 3; 
    const b = 4; // 报错
}

这就引发出了另外一问题 块作用域

块作用域是指变量在定义它的代码块或者说是大括号 {} 内有效的作用域。使用 let 或者 const 关键字声明的变量具有块级作用域(block scope),这意味着变量在包含它的块(在这个例子中是 for 循环的大括号内)以及任何嵌套的子块中都是可见的。

块作用域示例:

let blockScopedVariable = 'I am dhl';
if (true) {
    let blockScopedVariable = 'I am block scoped';
    console.log(blockScopedVariable); // 输出: I am block scoped
}
console.log(blockScopedVariable); // 输出: I am dhl

从执行结果可以看出,在 if 语句中定义的变量 blockScopedVariable,仅在代码块内有效,外层变量不会被内层同名变量的声明和赋值影响。

但是需要注意,在 ArkTS 中不能使用 for .. in,否则会有一个编译警告。

鸿蒙,ArkTs 一段诡异的代码_Android

之所以不能使用 for .. in 是因为在 ArkTS 中,对象的布局在编译时是确定的,且不能在程序执行期间更改对象的布局,换句话说,ArkTS 禁止以下行为:

  • 向对象中添加新的属性或方法
  • 从对象中删除已有的属性或方法
  • 将任意类型的值赋值给对象属性

如果修改对象布局会影响代码的可读性以及运行时性能。

从开发的角度来说,在某处定义类,然后又在其它地方修改了实际对象布局,这很容易引入错误,另外如果修改对象布局,需要在运行时支持,这样会增加执行开销降低性能。

全文到这里就结束了,感谢你的阅读,如果文章对你有帮助,欢迎、点赞、分享给身边的小伙伴,你的点赞是我持续更新的动力。

Hi 大家好,我是 DHL,大厂程序员,公众号:ByteCode ,在美团、快手、小米工作过。分享有用的原创文章,涉及鸿蒙、Android、Java、Kotlin、性能优化、大厂面经。

举报

相关推荐

0 条评论