ArkTS 语言中 变量修饰符 有哪些?

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

在 ArkTS 语言中,变量修饰符主要分为以下几类,每个修饰符都有其特定的作用和使用场景:

1. 访问修饰符

控制变量或方法的访问权限。

修饰符作用示例
public默认修饰符,允许在任何地方访问public name: string = "Alice";
private仅在当前类内部可访问private _age: number = 20;
protected在当前类及其子类中可访问protected salary: number = 5000;

示例

class Person {
  public name: string;    // 公开属性
  private _id: number;   // 私有属性
  protected age: number; // 受保护属性

  constructor(name: string, id: number) {
    this.name = name;
    this._id = id;
  }
}

2. 只读修饰符

修饰符作用示例
readonly变量只能在声明时或构造函数中初始化,之后不可修改readonly PI: number = 3.14;

示例

class Circle {
  readonly PI: number = 3.14159;
  radius: number;

  constructor(radius: number) {
    this.radius = radius;
    // this.PI = 3.14; // 错误!readonly 变量不可二次赋值
  }
}

3. 静态修饰符

修饰符作用示例
static变量或方法属于类本身,而非实例static count: number = 0;

示例

class Counter {
  static count: number = 0; // 静态变量

  static increment() {      // 静态方法
    Counter.count++;
  }
}

console.log(Counter.count); // 直接通过类名访问

4. 类型修饰符

修饰符作用示例
const定义常量,编译时常量(ArkTS 中较少使用,通常用 readonly 替代)const MAX_SIZE: number = 100;
let定义块级作用域变量(默认变量声明方式)let message: string = "Hello";
var函数作用域变量(不推荐,ArkTS 优先用 letvar oldValue: number = 10;

letvar 的关键区别在于作用域let 是块级作用域({} 内有效),而 var 是函数作用域(整个函数内有效)。优先使用 let 可以避免变量泄露到全局或外层作用域,从而减少命名冲突和意外修改。

问题示例:var 的变量提升与污染

function exampleVar() {
  if (true) {
    var value = 10; // var 会提升到函数作用域
    console.log("Inner:", value); // 输出 10
  }
  console.log("Outer:", value); // 也能访问到 value(污染外层)
}
exampleVar();
// 输出:
// Inner: 10
// Outer: 10

问题var 声明的 value 泄露到了整个 exampleVar 函数作用域,即使它在 if 块中定义。

修复方案:使用 let 块级作用域

function exampleLet() {
  if (true) {
    let value = 10; // let 仅在 {} 块内有效
    console.log("Inner:", value); // 输出 10
  }
  console.log("Outer:", value); // 报错!value 未定义
}
exampleLet();
// 输出:
// Inner: 10
// Uncaught ReferenceError: value is not defined

优势

  1. value 仅在 if 块内有效,不会污染外层作用域。
  2. 避免与其他代码中的 value 变量冲突。

更复杂的场景对比

var 的陷阱:循环中的变量泄露
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 输出 3, 3, 3(全部指向同一个 i)
}

原因var i 属于函数作用域,循环结束后 i 的值为 3,所有 setTimeout 回调共享同一个 i

let 的块级作用域修复
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 输出 0, 1, 2
}

原因:每次循环 let i 会创建一个新的块级作用域变量,setTimeout 回调捕获的是各自的 i。  

5. 其他特殊修饰符

修饰符作用示例
abstract抽象类/方法,需子类实现abstract class Shape { abstract area(): number; }
override表示方法覆盖父类实现override toString(): string { return "Custom"; }

示例

abstract class Animal {
  abstract makeSound(): void; // 抽象方法
}

class Dog extends Animal {
  override makeSound() {      // 必须实现抽象方法
    console.log("Woof!");
  }
}

关键区别总结

修饰符作用域可变性典型用途
public全局可修改类公开属性
private类内部可修改内部状态隐藏
readonly全局/类不可修改常量或初始化后不变的属性
static类级别可修改全局计数器或工具方法
let块级作用域可修改局部变量

何时使用哪种修饰符?

  1. 需要封装数据 → private / protected
  2. 定义常量 → readonly
  3. 共享类级别数据 → static
  4. 覆盖父类方法 → override
  5. 避免全局污染 → 优先用 let 而非 var

ArkTS 的修饰符设计沿袭了 TypeScript 的特性,但更强调静态类型安全和面向对象规范。实际开发中应优先使用 letreadonly 和访问控制修饰符(public/private)来保证代码的可维护性。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值