鸿蒙学习实战之路:ArkTS基础函数定义与调用

ArkTS基础函数定义与调用

文章简介

在HarmonyOS应用开发中,ArkTS作为基于TypeScript的扩展语言,函数是其核心编程概念之一。本文将系统讲解ArkTS中函数的定义、参数传递、返回值处理等关键知识点,通过丰富的代码示例帮助开发者掌握函数的使用技巧。

官方参考资料:

函数定义基础

基本函数定义语法

ArkTS中的函数定义遵循TypeScript语法规范,同时结合HarmonyOS特性进行了扩展。

// 最简单的函数定义
function greet(): void {
  console.log('Hello, HarmonyOS!');
}

// 带参数的函数
function calculateArea(width: number, height: number): number {
  return width * height;
}

// 箭头函数
const multiply = (a: number, b: number): number => {
  return a * b;
};

函数定义的关键组成部分

  • function关键字:声明一个函数
  • 函数名:遵循标识符命名规则
  • 参数列表:可接受零个或多个参数
  • 返回类型:指定函数返回值的数据类型
  • 函数体:包含具体执行逻辑的代码块

函数参数详解

必需参数与可选参数

// 必需参数
function createUser(name: string, age: number): void {
  console.log(`用户: ${name}, 年龄: ${age}`);
}

// 可选参数(使用?标识)
function configureDevice(deviceName: string, timeout?: number): void {
  const actualTimeout = timeout || 3000;
  console.log(`配置设备: ${deviceName}, 超时: ${actualTimeout}ms`);
}

// 调用示例
createUser("张三", 25);        // 正确
configureDevice("智能音箱");    // timeout使用默认值
configureDevice("智能电视", 5000); // 指定timeout

默认参数值

// 带默认值的参数
function connectWifi(ssid: string, password: string = "12345678"): boolean {
  console.log(`连接WiFi: ${ssid}, 密码: ${password}`);
  return true;
}

// 调用示例
connectWifi("HomeNetwork");              // 使用默认密码
connectWifi("OfficeNetwork", "office888"); // 指定密码

剩余参数

// 剩余参数(可变参数)
function logSensorData(sensorType: string, ...readings: number[]): void {
  console.log(`传感器类型: ${sensorType}`);
  readings.forEach((reading, index) => {
    console.log(`读数${index + 1}: ${reading}`);
  });
}

// 调用示例
logSensorData("温度传感器", 25.6, 26.1, 24.8);
logSensorData("湿度传感器", 65, 68);

返回值处理

基本返回值

// 返回基本类型
function getDeviceInfo(): string {
  return "HarmonyOS Device v2.0";
}

// 返回对象
function createCoordinate(x: number, y: number): {x: number, y: number} {
  return { x, y };
}

// 返回数组
function getSupportedResolutions(): number[] {
  return [720, 1080, 1440, 2160];
}

异步函数与Promise返回

// 异步函数定义
async function fetchNetworkData(url: string): Promise<string> {
  // 模拟网络请求
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`从 ${url} 获取的数据`);
    }, 1000);
  });
}

// 使用async/await调用
async function loadData(): Promise<void> {
  try {
    const data = await fetchNetworkData("https://api.example.com/data");
    console.log("获取到的数据:", data);
  } catch (error) {
    console.error("数据获取失败:", error);
  }
}

函数类型与高级特性

函数类型注解

// 定义函数类型
type MathOperation = (a: number, b: number) => number;

// 使用函数类型
const add: MathOperation = (x, y) => x + y;
const subtract: MathOperation = (x, y) => x - y;

// 函数作为参数
function calculate(a: number, b: number, operation: MathOperation): number {
  return operation(a, b);
}

// 调用示例
const result1 = calculate(10, 5, add);      // 15
const result2 = calculate(10, 5, subtract); // 5

函数重载

// 函数重载声明
function processInput(input: string): string;
function processInput(input: number): number;
function processInput(input: boolean): boolean;

// 函数实现
function processInput(input: any): any {
  if (typeof input === 'string') {
    return input.toUpperCase();
  } else if (typeof input === 'number') {
    return input * 2;
  } else if (typeof input === 'boolean') {
    return !input;
  }
}

// 调用示例
console.log(processInput("hello")); // "HELLO"
console.log(processInput(10));      // 20
console.log(processInput(true));    // false

函数调用实践

基本调用方式

// 直接调用
function showNotification(message: string): void {
  console.log(`通知: ${message}`);
}

showNotification("系统更新完成");

// 方法调用(作为对象属性)
const deviceUtils = {
  getBatteryLevel: (): number => {
    return 85; // 模拟电池电量
  },
  restart: (): void => {
    console.log("设备重启中...");
  }
};

const battery = deviceUtils.getBatteryLevel();
deviceUtils.restart();

回调函数使用

// 定义回调函数类型
type OperationCallback = (result: number) => void;

// 使用回调函数
function complexCalculation(
  values: number[], 
  callback: OperationCallback
): void {
  let sum = 0;
  for (const value of values) {
    sum += value;
  }
  callback(sum);
}

// 调用带回调的函数
complexCalculation([1, 2, 3, 4, 5], (result) => {
  console.log(`计算结果: ${result}`);
});

立即执行函数(IIFE)

// 立即执行函数
const appConfig = (() => {
  const config = {
    version: "1.0.0",
    apiEndpoint: "https://api.harmonyos.com",
    timeout: 5000
  };
  
  // 返回配置对象的只读副本
  return Object.freeze(config);
})();

console.log(`应用版本: ${appConfig.version}`);

实际应用案例

HarmonyOS组件中的函数使用

@Entry
@Component
struct DeviceController {
  @State deviceStatus: string = 'offline';
  
  // 组件内的方法
  private toggleDevice(): void {
    this.deviceStatus = this.deviceStatus === 'online' ? 'offline' : 'online';
    console.log(`设备状态切换为: ${this.deviceStatus}`);
  }
  
  // 带参数的方法
  private setDeviceBrightness(level: number): void {
    if (level < 0 || level > 100) {
      console.error('亮度值必须在0-100之间');
      return;
    }
    console.log(`设置设备亮度为: ${level}%`);
  }
  
  build() {
    Column() {
      Text(`设备状态: ${this.deviceStatus}`)
        .fontSize(20)
      
      Button('切换状态')
        .onClick(() => {
          this.toggleDevice();
        })
      
      Button('设置亮度为50%')
        .onClick(() => {
          this.setDeviceBrightness(50);
        })
    }
    .padding(20)
    .width('100%')
  }
}

工具函数集合示例

// 设备工具函数集合
class DeviceUtils {
  // 静态方法 - 不需要实例化即可调用
  static validateMacAddress(mac: string): boolean {
    const macRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
    return macRegex.test(mac);
  }
  
  // 实例方法
  formatStorageSize(bytes: number): string {
    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;
    
    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }
    
    return `${size.toFixed(2)} ${units[unitIndex]}`;
  }
}

// 使用示例
const isValid = DeviceUtils.validateMacAddress("00:1B:44:11:3A:B7");
console.log(`MAC地址验证结果: ${isValid}`);

const utils = new DeviceUtils();
const formattedSize = utils.formatStorageSize(15483264);
console.log(`格式化存储大小: ${formattedSize}`);

参数配置表格

常用函数参数选项

参数类型 语法示例 适用场景 注意事项
必需参数 (name: string) 函数必须的参数 调用时必须提供
可选参数 (timeout?: number) 可选的配置参数 使用前检查undefined
默认参数 (retries: number = 3) 有默认值的参数 默认值在函数定义时计算
剩余参数 (...values: number[]) 数量不定的参数 在函数内作为数组使用
对象参数 (config: {url: string, method: string}) 复杂的配置选项 建议使用接口定义类型

函数修饰符比较

修饰符 示例 作用 使用场景
async async function fetchData() 声明异步函数 需要await操作的函数
private private init() 私有方法 类内部使用的方法
static static create() 静态方法 不需要实例化的工具方法
readonly readonly config 只读属性 不希望被修改的配置

注意事项与最佳实践

⚠️ 重要提示

版本兼容性说明:

  • 本文代码基于HarmonyOS 4.0+ 和 ArkTS 3.0+
  • 异步函数语法需要API version 8+
  • 函数类型注解需要完整的TypeScript支持

常见陷阱与解决方案:

// ❌ 错误示例:可选参数在必需参数之前
function badExample(optionalParam?: string, requiredParam: string): void {
  // 这会导致编译错误
}

// ✅ 正确示例:必需参数在前,可选参数在后
function goodExample(requiredParam: string, optionalParam?: string): void {
  console.log(requiredParam, optionalParam);
}

// ❌ 错误示例:箭头函数中的this指向问题
class ProblematicClass {
  value: number = 10;
  
  problematicMethod(): void {
    setTimeout(() => {
      console.log(this.value); // 可能无法正确访问this
    }, 1000);
  }
}

// ✅ 正确示例:使用普通函数或绑定this
class CorrectClass {
  value: number = 10;
  
  correctMethod(): void {
    setTimeout(() => {
      console.log(this.value); // 箭头函数捕获外层this
    }, 1000);
  }
}

性能优化建议

  1. 避免在渲染函数中定义函数

    // ❌ 不推荐:每次渲染都会创建新函数
    build() {
      const handleClick = () => { /* ... */ };
      return Button('点击').onClick(handleClick);
    }
    
    // ✅ 推荐:使用类方法或useCallback
    private handleClick = (): void => { /* ... */ };
    build() {
      return Button('点击').onClick(this.handleClick);
    }
    
  2. 合理使用函数记忆化

    // 使用缓存优化计算密集型函数
    const memoizedCalculation = (() => {
      const cache = new Map<string, number>();
      
      return (input: string): number => {
        if (cache.has(input)) {
          return cache.get(input)!;
        }
        
        // 复杂计算
        const result = /* 计算逻辑 */;
        cache.set(input, result);
        return result;
      };
    })();
    

实战练习步骤

练习:创建设备管理工具函数

步骤1:定义基础函数

// 设备状态管理函数
function validateDeviceId(deviceId: string): boolean {
  return deviceId.length >= 5 && deviceId.length <= 32;
}

function generateDeviceToken(prefix: string = "DEV"): string {
  const timestamp = new Date().getTime();
  const random = Math.random().toString(36).substring(2, 8);
  return `${prefix}_${timestamp}_${random}`;
}

步骤2:创建配置管理函数

interface DeviceConfig {
  name: string;
  type: 'sensor' | 'actuator' | 'controller';
  pollingInterval?: number;
  retryCount?: number;
}

function createDeviceConfig(
  name: string, 
  type: DeviceConfig['type'],
  options: { pollingInterval?: number, retryCount?: number } = {}
): DeviceConfig {
  return {
    name,
    type,
    pollingInterval: options.pollingInterval || 5000,
    retryCount: options.retryCount || 3
  };
}

步骤3:实现批量操作函数

async function batchDeviceOperation(
  deviceIds: string[],
  operation: (deviceId: string) => Promise<boolean>
): Promise<{ success: string[], failed: string[] }> {
  const success: string[] = [];
  const failed: string[] = [];
  
  for (const deviceId of deviceIds) {
    try {
      const result = await operation(deviceId);
      if (result) {
        success.push(deviceId);
      } else {
        failed.push(deviceId);
      }
    } catch (error) {
      failed.push(deviceId);
      console.error(`设备 ${deviceId} 操作失败:`, error);
    }
  }
  
  return { success, failed };
}

步骤4:测试函数功能

// 测试代码
async function testDeviceFunctions(): Promise<void> {
  // 测试设备ID验证
  console.log('设备ID验证:', validateDeviceId('my_device_001'));
  
  // 测试令牌生成
  console.log('设备令牌:', generateDeviceToken());
  
  // 测试配置创建
  const config = createDeviceConfig('温度传感器', 'sensor', { pollingInterval: 3000 });
  console.log('设备配置:', config);
  
  // 测试批量操作
  const results = await batchDeviceOperation(
    ['dev1', 'dev2', 'dev3'],
    async (id) => {
      // 模拟设备操作
      return Math.random() > 0.3; // 70%成功率
    }
  );
  
  console.log('批量操作结果:', results);
}

总结

通过本文的学习,你应该掌握了:

  • ✅ ArkTS函数的基本定义语法和调用方式
  • ✅ 各种参数类型的正确使用方法
  • ✅ 函数返回值的处理和类型注解
  • ✅ 高级函数特性如重载、回调、异步函数
  • ✅ 在HarmonyOS组件中合理使用函数
  • ✅ 函数性能优化和最佳实践

函数是ArkTS编程的基础,熟练掌握函数的使用能够大大提高HarmonyOS应用开发的效率和质量。建议在实际开发中多加练习,逐步掌握更多高级函数技巧。


扩展学习资源:

需要参加鸿蒙认证的请点击 鸿蒙认证链接

posted @ 2025-11-26 17:06  时间煮鱼  阅读(29)  评论(0)    收藏  举报