在这里插入图片描述


函数声明

在 ArkTS 中,函数是组织代码逻辑的基本单元。函数声明用于定义一个具有名称、参数列表、返回类型和函数体的可重用代码块。与 TypeScript 类似,ArkTS 要求显式标注参数类型和返回类型,以增强类型安全性和编译期检查能力。

以下是一个典型的函数声明示例及其语义说明:

  1. 参数类型标注x: string, y: string 明确指定每个参数的数据类型为字符串。
  2. 返回值类型: string 表示该函数必须返回一个字符串类型的值。
  3. 函数体:包含具体的执行逻辑,此处使用模板字符串拼接两个输入。
@Entry
@Component
struct Index {
  build() {
    Column(){
      // 函数
      Button('函数测试:').onClick(()=>{
        console.log(add('你好','VON'))
      })
    }
  }
}

function add(x: string, y: string): string {
  let z: string = `${x} ${y}`;
  return z;
}

💡 提示:ArkTS 不允许省略返回类型(除非函数无返回值且使用 void 显式声明),这是其强类型特性的体现之一。

在这里插入图片描述


可选参数

在实际开发中,某些函数参数可能并非总是需要传入。为此,ArkTS 支持可选参数,其语法为 name?: Type。带有 ? 的参数在调用时可以省略,此时其值为 undefined

例如:

function hello(name?: string) {
  if (name == undefined) {
    console.info('函数测试:Hello!');
  } else {
    console.info(`函数测试:Hello, ${name}!`);
  }
}

⚠️ 注意:由于可选参数可能为 undefined,在使用前应进行判空处理,避免运行时错误。

另一种实现“可选”效果的方式是使用默认参数值。当调用函数时未提供该参数,将自动使用预设的默认值。

function multiply(n: number, coeff: number = 2): number {
  return n * coeff;
}

在上述例子中,coeff 的默认值为 2。因此:

  • multiply(5) 等价于 multiply(5, 2),结果为 10
  • multiply(5, 3) 则使用传入的 3,结果为 15

最佳实践:优先使用默认参数而非可选参数 + 条件判断,代码更简洁且语义更清晰。

在这里插入图片描述
在这里插入图片描述


Rest 参数

当函数需要接收不定数量的参数时,可以使用 Rest 参数(剩余参数)。Rest 参数必须是函数的最后一个参数,其语法为 ...restName: Type[],表示将剩余的所有实参收集到一个数组中。

例如,以下 sum 函数可以计算任意多个数字的总和:

function sum(...numbers: number[]): number {
  let res = 0;
  for (let n of numbers) {
    res += n;
  }
  return res;
}

sum();           // 返回 0(空数组)
sum(1, 2, 3);    // 返回 6
sum(10, 20, 30, 40); // 返回 100

🔍 原理:Rest 参数本质上是将多个独立参数“打包”成一个数组,便于统一处理。它常用于工具函数(如日志记录、数学运算、事件监听等)。

在这里插入图片描述


箭头函数(又名 Lambda 函数)

ArkTS 支持 箭头函数(Arrow Function),这是一种更简洁的函数定义语法,特别适合用于回调、高阶函数或短小逻辑的表达。

基本形式如下:

let sum = (x: number, y: number): number => {
  return x + y;
}

ArkTS 允许在函数体仅为单个表达式时省略大括号和 return 关键字,此时返回类型可由编译器自动推断:

let sum1 = (x: number, y: number) => { return x + y; }
let sum2 = (x: number, y: number) => x + y; // 更简洁

两者完全等价,但 sum2 的写法更符合函数式编程风格。

🌟 优势

  • 语法简洁,减少样板代码;
  • 自动绑定外层作用域的 this(在类或组件中尤为重要);
  • 适合用于 mapfilterforEach 等数组方法。

在这里插入图片描述


闭包

闭包(Closure) 是指一个函数与其词法环境(即创建该函数时所在的作用域)的组合。闭包使得函数可以“记住”并访问其外部作用域中的变量,即使该函数在其原始作用域之外被调用。

在 ArkTS 中,闭包常用于状态保持、私有变量封装等场景。

以下示例展示了闭包的基本用法:

function f(): () => number {
  let count = 0;
  let g = (): number => { 
    count++; 
    return count; 
  };
  return g;
}

let z = f();
z(); // 返回:1
z(); // 返回:2

在这个例子中:

  • f 函数内部定义了局部变量 count 和箭头函数 g
  • g 捕获了 count,形成闭包;
  • 即使 f 执行完毕,count 也不会被销毁,而是被 g 持续引用;
  • 每次调用 z()(即 g),都会修改并返回同一个 count 的值。

🔒 应用场景:计数器、缓存、模块化私有状态、防抖/节流函数等。

在这里插入图片描述


函数重载

函数重载(Function Overloading) 允许为同一个函数名定义多个不同的调用签名(即参数类型或数量不同),从而支持多种调用方式。这在 API 设计中非常有用,可以提升代码的灵活性和可读性。

在 ArkTS 中,函数重载通过多个同名但参数列表不同的声明来实现,最后提供一个统一的函数体来处理所有情况。

例如:

// 重载声明(仅签名,无函数体)
function foo(x: number): string;         // 接收数字
function foo(x: string): string;         // 接收字符串

// 实际实现(需兼容所有重载签名)
function foo(x: number | string): string {
  return typeof x === 'number'
    ? `Number: ${x}`
    : `String: ${x}`;
}

console.info('重载测试:', foo(123));   // 输出:Number: 123
console.info('重载测试:', foo('VON')); // 输出:String: VON

⚠️ 重要限制

  • 所有重载签名必须参数列表不同(类型、数量或顺序不同);
  • 不允许两个重载具有完全相同的参数列表,否则会引发编译错误;
  • 实现函数的参数类型必须是所有重载签名的联合类型

💡 提示:函数重载不会生成多个函数,而是在编译期根据调用上下文选择最匹配的签名,运行时仍只有一个函数体。

在这里插入图片描述


通过以上内容,您已经掌握了 ArkTS 中函数的核心特性:从基础声明到高级用法(如闭包、重载),涵盖了日常开发中的绝大多数场景。合理运用这些特性,不仅能提升代码的健壮性,还能增强程序的表达力与可维护性。

全套代码

@Entry
@Component
struct Index {
  build() {
    Column(){
      // 函数
      Button('函数测试').onClick(()=>{
        console.log(add('你好','VON'))
        hello()
        hello('VON')
        console.info('函数测试:', multiply(2));// 返回2*2
        console.info('函数测试:', multiply(2,3));// 返回2*3

        console.info('函数测试:', sum());// 返回0
        console.info('函数测试:', sum(1, 2, 3));// 返回6

        let bsum = (x: number, y: number): number => {
          return x + y;
        }
        let sum1 = (x: number, y: number) => { return x + y; }
        let sum2 = (x: number, y: number) => x + y
        console.info('函数测试:', sum1(1, 2));
        console.info('函数测试:', sum2(1, 2));

        let z = f();
        console.info('闭包测试:',z() );// 返回:1
        console.info('闭包测试:',z() );// 返回:2
        console.info('闭包测试:',z() );// 返回:3

        console.info('重载测试:',foo(123));//OK,使用第一个定义
        console.info('重载测试:',foo('VON'));//OK,使用第二个定义
      })
    }
  }
}
//函数声明
function add(x: string, y: string): string {
  let z: string = `${x} ${y}`;
  return z;
}
//可选参数
function hello(name?: string) {
  if (name == undefined) {
    console.info('函数测试:Hello!');
  } else {
    console.info(`函数测试:Hello, ${name}!`);
  }
}
function multiply(n: number, coeff: number = 2): number {
  return n * coeff;
}
//rest参数
function sum(...numbers: number[]): number {
  let res = 0;
  for (let n of numbers) {
    res += n;
  }
  return res;
}
// 闭包
function f(): () => number {
  let count = 0;
  let g = (): number => { count++; return count; };
  return g;
}

// 重载声明带返回值
function foo(x: number): string;         // 返回字符串
function foo(x: string): string;         // 返回字符串
function foo(x: number | string): string { // 统一实现
  return typeof x === 'number'
    ? `Number: ${x}`
    : `String: ${x}`;
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐