常用系统对象
在鸿蒙系统开发中,用于定义对象结构,其键为字符串类型,值可为任意类型,主要用于实现属性映射和复杂数据结构管理。。
Record
在鸿蒙(HarmonyOS)ArkTS开发中,Record 是一个工具类型,用于构造对象类型,其属性键为指定类型 Keys,属性值为指定类型 Type。它常用于将一种类型的属性映射到另一种类型,尤其适合处理键值对的集合场景。以下是具体说明和示例:
1. 基本语法
type RecordType = Record<Keys, Type>;
- **
Keys**:对象键的类型(通常是联合类型)。 - **
Type**:对象值的类型。
2. 使用示例
场景:学生成绩管理系统
// 定义课程联合类型
type Course = 'Math' | 'Chinese' | 'English';
// 定义成绩类型
type Grade = number;
// 使用Record定义学生成绩类型:键为课程,值为成绩
type StudentGrades = Record<Course, Grade>;
// 使用Record定义班级成绩类型:键为学号,值为学生成绩对象
type ClassGrades = Record<string, StudentGrades>;
// 学生成绩对象(符合StudentGrades类型)
let student1: StudentGrades = { Math: 90, Chinese: 85, English: 92 };
let student2: StudentGrades = { Math: 78, Chinese: 82, English: 85 };
// 班级成绩记录(符合ClassGrades类型)
const classGrades: ClassGrades = {
'001': student1,
'002': student2
};
@Entry
@Component
struct Index {
// 根据学号计算平均分
getAverageGrade(studentId: string, grades: ClassGrades): number | null {
const studentGrades = grades[studentId];
if (!studentGrades) {
console.log(`Student with ID ${studentId} not found.`);
return null;
}
// 获取课程数组并计算总分
const courses = Object.keys(studentGrades) as Course[];
const total = courses.reduce((sum, course) => sum + studentGrades[course], 0);
return total / courses.length; // 返回平均分
}
build() {
Column() {
Button('计算平均分')
.onClick(() => {
// 输出:89
console.log('学生平均分:', this.getAverageGrade('001', classGrades));
})
}
}
}
3. 常用操作
遍历
let record: Record<string, number> = { "width": 666, "height": 888 };
// 先获取allkey,再遍历
const keys = Object.keys(record); // 返回 ['width', 'height']
for (let key of keys) {
console.log(`Key: ${key}, Value: ${record[key]}`);
}
// 或写
keys.forEach(key => {
console.log(`Key: ${key}, Value: ${record[key]}`);
});
// 直接获取allkey对其进行遍历
Object.keys(record).forEach(key => {
console.log(`Key: ${key}, Value: ${record[key]}`);
});
4. 关键点说明
- 类型安全:
Record确保对象键和值的类型严格匹配,避免运行时错误。 - 灵活性:支持嵌套使用(如
ClassGrades中值类型为另一个Record)。 - 实用场景:适用于动态键名集合(如数据库查询结果、配置映射表)。
注意:若需处理音频录制等底层能力,请使用鸿蒙推荐的
AVRecorder替代废弃的AudioRecorderAPI(参考检索信息)。Record类型仅用于类型定义,与多媒体录制无关。
string
charCodeAt(index: number): number方法
作用:返回指定位置字符的 Unicode 值。 @param index 所需字符的从零开始的索引。如果指定索引处没有字符,则返回 NaN。
split(separator: string | RegExp, limit?: number): string[];
作用:使用指定的分隔符将字符串分割成多个子字符串,并以数组形式返回。
separator: 分隔符,可以是字符串或正则表达式。需要注意的是,如果分隔符是正则表达式中的特殊字符(如点号.),你需要使用双反斜杠进行转义,例如应写为 split("\\.")而不是 split(".")。limit (可选): 一个数字,用于限制返回数组的最大长度。如果指定了该参数,则分割不会超过这个限制,返回的数组最多包含 limit 个元素。
关键特性与行为
了解 split() 方法的一些特定行为,有助于你更好地使用它:
-
处理连续分隔符与空字符串:在鸿蒙Next中,
split()方法在遇到连续的分隔符时,其行为可能与某些其他编程语言或环境不同。它会忽略由此产生的空字符串。例如,分割"a,,b"会返回["a", "b"],而不是["a", "", "b"]。 -
无匹配分隔符的处理:如果字符串中没有找到指定的分隔符,
split()方法会返回一个包含原字符串的数组[原字符串]。 -
分隔符在开头或结尾:当分隔符出现在字符串开头或结尾时,同样需要注意产生的空字符串会被忽略。
代码示例
下面通过几个例子来展示 split() 方法在不同场景下的应用:
处理特殊字符分隔符
let filename: string = "main.page.ts";
let components: string[] = filename.split("\\."); // 注意:点号需要转义
console.log(components); // 输出: ["main", "page", "ts"] [citation:5]
注意,在鸿蒙Next中,对于点号这样的特殊字符,在split中需要使用双反斜杠转义。但实际ArkTS/TypeScript中,split方法的分隔符参数如果是字符串,通常不需要像正则表达式那样对点号进行转义。这一点建议你根据实际开发环境进行验证。
trim()、trimStart()、trimEnd()
在鸿蒙(HarmonyOS)应用开发中,如果你使用的是ArkTS语言,那么处理字符串首尾空白字符会非常方便,因为它直接使用了JavaScript/TypeScript的标准字符串方法。下面这个表格汇总了相关方法的核心用法:
| 方法名 | 作用 | 参数说明 | 返回值 |
|---|---|---|---|
trim() |
去除字符串首尾所有空白字符 | 无 | 一个新的字符串,表示去除首尾空格后的结果 |
trimStart() |
仅去除字符串开头(左侧)的空白字符 | 无 | 一个新的字符串,表示去除左侧空格后的结果 |
trimEnd() |
仅去除字符串末尾(右侧)的空白字符 | 无 | 一个新的字符串,表示去除右侧空格后的结果 |
ResourceStr
在鸿蒙应用开发中,ResourceStr 和 string 是两种用于表示文本数据的类型,理解它们的区别对于编写正确且高效的代码非常重要。
为了帮你快速把握核心区别,可以参考下表:
| 对比维度 | ResourceStr |
string |
|---|---|---|
| 类型定义 | 联合类型:string | Resource |
TypeScript 基础字符串类型 |
| 本质 | 可以是字符串或资源引用 | 普通的字符串字面量 |
| 适用场景 | 组件属性,需同时支持本地化资源引用和普通字符串 | 硬编码文本、网络数据、动态拼接字符串 |
| 灵活性 | 高,可接受两种类型值 | 低,仅接受字符串 |
| 多语言支持 | 支持,通过资源引用自动切换 | 不支持,内容固定 |
如何选择和使用
在实际编码中,你可以根据以下场景来决定使用哪种类型:
-
使用
string类型:-
当文本内容是固定的,不需要随系统语言改变,例如某些内部标识、调试日志。
-
当文本内容来自网络请求或用户动态输入。
// 固定字符串 let fixedText: string = "这是一个静态文本"; // 来自网络的字符串 let networkData: string = await fetchDataFromNetwork();
-
-
使用
ResourceStr类型:-
当组件的文本属性既可能显示本地化资源,又可能显示普通字符串时。例如,一个通用的按钮组件,可能显示资源文件中定义的"确认",也可能直接显示一个像"点击我"这样的普通字符串。
// 使用资源引用 let localizedText: ResourceStr = $r('app.string.submit_button'); // 也可以直接使用字符串 let plainText: ResourceStr = "直接显示的文本"; // 在组件中使用 Text(localizedText) Text(plainText) -
-
使用
Resource类型:-
当你明确需要引用
resources目录下定义的资源时,例如通过$r('app.string.hello')或$rawfile('filename')方式引用的字符串、图片等。这确保了资源能被系统正确管理并支持多语言、深浅色模式等。
// 专门用于资源引用 let resourceOnly: Resource = $r('app.string.hello_world'); Text(resourceOnly) -
类型转换与比较
-
类型转换:有时你可能会遇到需要将
Resource类型转换为string的情况,例如在某些不支持Resource类型的组件或API中。这时可以使用资源管理器:typescript
import common from '@ohos.app.ability.common'; let context = getContext(this) as common.UIAbilityContext; // 将Resource转换为string let resourceString: Resource = $r('app.string.hello'); let extractedString: string = context.resourceManager.getStringSync(resourceString.id); console.log(extractedString === "Hello"); // 比较字符串需要注意的是,直接使用
==或===比较Resource对象和字符串通常不会得到预期的结果。建议先将Resource转换为string再比较,或者通过其他逻辑(如对比关联的变量)来判断。 -
组件支持:大部分文本组件(如
Text)都支持ResourceStr类型。但一些特殊组件(如跑马灯、搜索框、富文本编辑器)可能仅支持string类型,这时就需要按上述方法进行转换。
数组
高阶函数
| 函数分类 | 核心函数 | 主要作用 | 鸿蒙开发中的典型应用场景 |
|---|---|---|---|
| 集合处理 | map() |
转换数组中的每个元素,并返回新数组。 | 将数据模型列表映射为对应的UI组件列表,例如将商品数组转换为ForEach中的商品卡片。 |
filter() |
过滤数组,返回满足条件的新数组。 | 筛选数据,例如从所有消息中过滤出非空消息,或从列表中筛选出偶数。 | |
reduce() |
将数组元素累积计算为一个单一结果。 | 计算总和、平均值等。 | |
forEach() |
遍历数组,执行副作用操作,无返回值。 | 简单遍历数组,例如打印日志。 | |
find() / some() / every() |
查询数组中满足条件的元素。 | 检查列表中是否存在(some)或所有元素都满足(every)某个条件。 |
const numbers = [1, 2, 3];
// 1. map: 转换元素
const squared = numbers.map(x => x * x); // [1, 4, 9]
// 2. filter: 筛选元素
const evens = numbers.filter(x => x % 2 === 0); //
// 3. reduce: 累积计算
const sum = numbers.reduce((acc, cur) => acc + cur, 0); // 6
// 4. find()用来查找数组中满足条件的第一个元素
Let find = array.find(num => num === 2)
// 5. sort()用来实现数组排序
Let sort1 = array.sort((a,b) => a - b)//1,2,3,4,5 升序
Let sort2 = array.sort((a,b) => b - a)//5,4,3,2,1 降序
//链式调用举例
let numbers = [1, 2, 3, 4, 5];
let result = numbers
.filter(it => it % 2 === 0) // 过滤出偶数 [2, 4]
.map(it => it * it) // 计算平方 [4, 16]
.reduce((sum, value) => sum + value, 0); // 求和 20
println(result);
常用函数
slice(start?: number, end?: number): T[];
下面表格总结了 slice 方法不同参数的情况:
| 调用方式 | 返回结果 | 说明 |
|---|---|---|
arr.slice(-1) |
包含原数组最后1个元素的新数组 | 负数表示从数组末尾开始的偏移量 |
arr.slice(-2) |
包含原数组最后2个元素的新数组 | - |
arr.slice(1, 4) |
从索引1(包含)到索引4(不包含)的元素 | 左闭右开区间 |
arr.slice(0, -1) |
从开始到倒数第二个元素的新数组 | 常用于复制并排除最后一个元素 |
汉字转拼音
在鸿蒙应用开发中,i18n.Transliterator.getInstance() 方法用于获取一个文本转写器,其主要功能之一就是实现汉字转拼音。
| 转写模式 | 说明 | 示例(输入:"中国") |
|---|---|---|
Any-Latn |
将文本(如汉字)转换为带声调的拉丁字母(拼音) | zhōng guó |
Latin-ASCII |
将带声调的拼音转换为不带声调的纯ASCII形式 | zhong guo |
如何使用
-
导入模块:首先,确保在你的代码文件中导入国际化工具包。
import { i18n } from '@kit.LocalizationKit';
-
转换实战:你可以直接使用单一模式,也可以组合两种模式,实现从汉字到无注音拼音的转换。
// 1. 转换为带声调的拼音 let transliteratorToTone = i18n.Transliterator.getInstance('Any-Latn'); let pinyinWithTone = transliteratorToTone.transform('你好,世界!'); console.info(`带声调拼音: ${pinyinWithTone}`); // 输出示例:nǐ hǎo, shì jiè! // 2. 转换为不带声调的拼音(组合使用) let transliteratorToTone2 = i18n.Transliterator.getInstance('Any-Latn'); let transliteratorToPlain = i18n.Transliterator.getInstance('Latin-ASCII'); let chineseText = "苹果"; let intermediate = transliteratorToTone2.transform(chineseText); // 先转带声调拼音 let finalPinyin = transliteratorToPlain.transform(intermediate); // 再去声调 console.info(`不带声调拼音: ${finalPinyin}`); // 输出示例:ping guo
重要说明
-
模式组合:鸿蒙的
Transliterator目前主要提供上述两种与拼音相关的模式。如果需要得到不带声调的拼音,就需要像示例中那样,先将汉字转为带声调拼音,再使用Latin-ASCII模式去除声调。 -
多音字处理:需要注意的是,这个接口对于多音字的处理可能无法保证100%准确。在开发对多音字要求苛刻的场景(如人名、地名处理)时,需要留意这一点。
-
功能定位:
i18n.Transliterator主要用于字符转写,如果需要进行精确的拼音转换(尤其是在商业级应用中),你可能需要评估是否能接受其精度。有更高要求时,可以考虑集成更专门的第三方拼音库。
ListScroller
基于鸿蒙(HarmonyOS)ArkTS开发规范,ListScroller是List组件的滚动控制器,用于精确控制列表滚动行为。List初始化时注入控制器:List({ scroller: this.listScroller })。核心功能如下:
核心方法 scrollToIndex()
listScroller.scrollToIndex( index: number, smooth?: boolean, align?: ScrollAlign )
- 参数说明:
index:目标列表项的下标(从0开始)smooth:是否启用平滑滚动(默认true)align:滚动对齐方式,可选值:ScrollAlign.START:目标项对齐列表顶部ScrollAlign.CENTER:目标项居中显示 ✅ScrollAlign.END:目标项对齐列表底部
使用注意事项
当列表数据异步加载时,需确保数据加载完成后再执行滚动。
// 错误示例:数据未加载完成就滚动
this.listScroller.scrollToIndex(4);
this.productList.unshift('新增项'); // 数据变更导致下标偏移
// 正确方案:延迟二次滚动
this.listScroller.scrollToIndex(targetIndex);
setTimeout(() => {
this.listScroller.scrollToIndex(targetIndex); // 500ms后重新校准
}, 500);
点击居中效果
@Component
struct CityList {
private listScroller: ListScroller = new ListScroller()
@State focusIndex: number = 0
build() {
List({ scroller: this.listScroller }) {
ForEach(this.cityData, (item, index) => {
ListItem() {
Text(item.name)
.onClick(() => {
this.focusIndex = index;
this.listScroller.scrollToIndex(index, true, ScrollAlign.CENTER); // 关键参数
})
}
})
}
}
}
解决滚动位置错误
若遇滚动后位置偏移,需检查:
- 数据稳定性:滚动前是否触发数据变更(如
unshift()/splice()) - 异步时序:网络加载完成前避免滚动操作
- 组件渲染:确保目标列表项已完成布局渲染
操作符
!== 和 !=
对比说明
在鸿蒙应用开发中,!== 和 != 都是用于比较的操作符,它们的核心区别在于比较时是否进行类型转换。为了让你能快速抓住要点,我先用一个表格来汇总它们的核心差异:
| 比较维度 | !== (严格不相等) |
!= (不相等) |
|---|---|---|
| 类型检查 | ✅ 严格:类型不同直接返回true |
❌ 宽松:先尝试转换类型再比较 |
| 值比较 | 仅在类型相同时,比较值是否不同 | 类型转换后,比较值是否不同 |
| 推荐度 | ⭐⭐⭐⭐⭐ 推荐使用,结果更精确 | ⭐⭐ 可能产生预期外的结果 |
核心要点与最佳实践
-
优先使用
!==:在鸿蒙的ArkTS(声明式TypeScript)开发中,,应尽量使用!==进行比较,以避免因隐式类型转换导致的潜在错误。有一个比较常见的例外是,如果需要同时判断一个值是否为null或undefined,可以使用x == null,因为它等价于x === null || x === undefined。 -
理解比较逻辑:
!=的比较逻辑是"先转换,再比较",而!==是"先看类型,类型不同就直接不相等,相同再比较值"。 -
注意特殊值:在处理
NaN时需要特别小心,因为NaN与任何值(包括它自己)进行宽松相等(==)或严格相等(===)比较时,结果都是false。如果需要判断一个值是否为NaN,可以使用isNaN()函数。
=== 和 ==
对比说明
在鸿蒙应用开发中,=== 和 == 都是用于比较的操作符,它们的核心区别在于比较时是否进行类型转换。下面这个表格清晰地展示了它们的主要差异:
| 比较维度 | === (严格相等) |
== (宽松相等) |
|---|---|---|
| 类型检查 | ✅ 严格:类型不同直接返回false |
❌ 宽松:先尝试转换类型再比较 |
| 值比较 | 仅在类型相同时,比较值是否相等 | 类型转换后,比较值是否相等 |
| 性能 | 稍快(无需类型转换) | 稍慢(需要类型转换) |
| 推荐度 | ⭐⭐⭐⭐⭐ 推荐使用 | ⭐⭐ 谨慎使用 |
特殊情况说明
// NaN 的比较
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
// 使用 isNaN() 判断
console.log(isNaN(NaN)); // true
// 空字符串、0、false 的宽松比较
console.log("" == 0); // true
console.log("" == false); // true
console.log(0 == false); // true
// 但严格比较都是 false
console.log("" === 0); // false
console.log("" === false); // false
console.log(0 === false); // false
最佳实践建议
-
优先使用
===:在鸿蒙的ArkTS开发中,强烈推荐使用===,因为:-
避免隐式类型转换导致的意外行为
-
代码意图更明确
-
更容易发现潜在的类型错误
-
-
谨慎使用
==:只有在明确需要类型转换时才使用==,比如:// 从输入框获取的值(字符串)与数字比较 let inputValue = "123"; if (inputValue == 123) { // 这里会执行,因为"123" == 123 } -
处理 null 和 undefined时建议使用==:
// 检查是否为 null 或 undefined if (value == null) { // 等价于 value === null || value === undefined } - 判断NaN时使用 isNaN() 判断
console.log(isNaN(NaN)); // true
URL常用操作
encodeURI
在鸿蒙应用开发中,declare function encodeURI(uri: string): string;是一个用于处理完整URL编码的全局方法。为了帮你快速理解它的核心要点,我先用一个表格来汇总:
| 特性 | 描述 |
|---|---|
| 主要作用 | 对整个统一资源标识符 进行编码 |
| 编码范围 | 处理空格等字符,但不编码协议头(http://)、域名部分以及/, ?, =, &, :, #等用于URL结构本身的保留字符 |
| 典型应用场景 | 当需要编码一个完整的URL字符串时使用 |
| 鸿蒙开发中的使用 | 可直接在ArkTS(基于TypeScript)的UI或逻辑代码中使用 |
与 encodeURIComponent 的区分
理解 encodeURI 和 encodeURIComponent 的区别至关重要,因为它们用于不同的场景:
-
encodeURI:适用于编码完整的URL。它会保留URL本身有特殊含义的功能字符(如:/?&=#),确保编码后的URL结构依然有效。 -
encodeURIComponent:适用于编码URL中的参数部分。它会编码几乎所有非标准字符,包括URL的功能字符。通常用于处理查询参数(即?后面的部分),防止参数中的特殊字符(如&,=)破坏URL结构。
简单来说,encodeURI 照顾整个URL的完整性,而 encodeURIComponent 确保参数部分的安全性。
更多推荐


所有评论(0)