【鸿蒙】鸿蒙开发过程中this指向问题
文章目录
- 什么是 `this`?
- 常见 `this` 指向问题
- 案例分析:HarmonyOS 组件中的 `this` 指向问题
- 问题描述
- 问题分析
- 原因
- 解决方案:绑定 `this` 的正确方法
- 方法一:使用箭头函数
- 方法二:手动绑定 `this`
- 完整代码示例
- 使用箭头函数
- 使用 `bind` 方法
- 总结
在 TypeScript 开发中,尤其是在使用面向对象编程(OOP)或基于组件的框架(如 HarmonyOS)时,this
的指向问题是一个常见且容易引发错误的挑战。本文将深入探讨 this
的绑定机制,并通过一个实际案例,展示如何在 TypeScript 中正确处理 this
的指向问题。
什么是 this
?
在 TypeScript 中,this
是一个关键字,代表当前对象的上下文。它指向调用该函数的对象,具体指向取决于函数的调用方式。
- 全局上下文:
this
指向全局对象(在浏览器中是window
,在 Node.js 中是global
)。 - 对象方法:
this
指向调用该方法的对象。 - 构造函数:
this
指向新创建的对象。 - 箭头函数:
this
指向定义时的上下文,而不是调用时的上下文。
常见 this
指向问题
在 TypeScript 开发中,this
指向问题通常出现在以下几种情况:
- 回调函数中的
this
:当一个方法作为回调函数传递给其他函数时,this
的指向可能会丢失。例如,在事件处理程序中,this
可能指向触发事件的元素,而不是组件实例。 - 嵌套函数中的
this
:在嵌套函数中,this
的指向可能会发生变化,导致无法访问到预期的对象属性。 - 类方法作为参数传递:当类的方法被作为参数传递给其他函数时,
this
的指向可能会丢失。
案例分析:HarmonyOS 组件中的 this
指向问题
需求:要根据上图,实现父组件与子组件联动的功能
问题描述
我们来看一个 HarmonyOS 组件的示例,其中包含一个 PropCase1
组件和一个 myProp
子组件。
@Entry
@Component
struct PropCase1 {@State num: number = 0syncData(s: number) {this.num = s}build() {Column({ space: 10 }) {Text(`父组件计算器:${this.num}`)Button('点击+1').width(100).height(50).borderRadius(20).onClick(() => {this.num++})Divider().color(Color.Gray).width('100%').strokeWidth(1)// 写法1// myProp({ num: this.num, f: (s: number) => {// this.num = s// }})// 写法2myProp({ num: this.num, f: this.syncData })}.height('100%').width('100%')}
}@Component
struct myProp {@Propnum: number;f: (s: number) => void = this.myFunmyFun(s: number): void { }@State action: boolean = falsebuild() {Column({ space: 10 }) {Text(`子组件计算器:${this.num.toString()}`)Button('点击+1').width(80).height(40).borderRadius(15).onClick(() => {this.num++this.f(this.num)})}}
}
问题分析
在上述代码中,PropCase1
组件将 syncData
方法作为回调函数传递给 myProp
子组件:
myProp({ num: this.num, f: this.syncData })
然而,当 myProp
子组件调用 f(this.num)
时,this.num
在 syncData
方法中并没有正确更新父组件的 num
,导致父组件无法接收到变化。
原因
- 上下文丢失:在写法2中,
syncData
方法在子组件中调用时,this
指向的是子组件,而不是父组件。因此,this.num
实际上是指向子组件的num
,而不是父组件的num
。 - 解决方法:需要确保
syncData
方法的this
正确绑定到父组件。
解决方案:绑定 this
的正确方法
方法一:使用箭头函数
箭头函数不会创建自己的 this
,它会捕获定义时的 this
上下文。因此,使用箭头函数可以确保 this
始终指向父组件。
myProp({ num: this.num, f: (s: number) => {this.num = s
}})
优点:
- 简单直接,不需要手动绑定
this
。 - 箭头函数自动捕获父组件的
this
上下文。
方法二:手动绑定 this
如果使用普通函数,需要手动绑定 this
,可以使用 bind
方法,或者使用箭头函数定义方法。
使用 bind
方法:
myProp({ num: this.num, f: this.syncData.bind(this) })
使用箭头函数定义方法:
syncData = (s: number) => {this.num = s
}
然后在传递时:
myProp({ num: this.num, f: this.syncData })
优点:
- 更加灵活,可以在需要时动态绑定
this
。 - 适用于需要在多个地方使用同一个方法的情况。
完整代码示例
以下是使用箭头函数和 bind
方法的完整代码示例:
使用箭头函数
@Entry
@Component
struct PropCase1 {@State num: number = 0syncData(s: number) {this.num = s}build() {Column({ space: 10 }) {Text(`父组件计算器:${this.num}`)Button('点击+1').width(100).height(50).borderRadius(20).onClick(() => {this.num++})Divider().color(Color.Gray).width('100%').strokeWidth(1)// 使用箭头函数myProp({ num: this.num, f: (s: number) => {this.num = s}})}.height('100%').width('100%')}
}
使用 bind
方法
@Entry
@Component
struct PropCase1 {@State num: number = 0syncData(s: number) {this.num = s}build() {Column({ space: 10 }) {Text(`父组件计算器:${this.num}`)Button('点击+1').width(100).height(50).borderRadius(20).onClick(() => {this.num++})Divider().color(Color.Gray).width('100%').strokeWidth(1)// 使用 bind 方法myProp({ num: this.num, f: this.syncData.bind(this) })}.height('100%').width('100%')}
}
总结
在 TypeScript 中,this
的指向问题是一个常见的挑战,尤其是在处理回调函数和方法引用时。通过使用箭头函数或手动绑定 this
,可以确保 this
始终指向预期的对象。
- 箭头函数 是最简单的方法,因为它自动捕获定义时的
this
上下文。 - 手动绑定 提供了更大的灵活性,适用于需要在多个地方使用同一个方法的情况。
通过正确处理 this
的指向,可以避免许多潜在的错误,并确保应用程序的稳定性和可维护性。
相关文章:

【鸿蒙】鸿蒙开发过程中this指向问题
文章目录 什么是 this?常见 this 指向问题案例分析:HarmonyOS 组件中的 this 指向问题问题描述问题分析原因 解决方案:绑定 this 的正确方法方法一:使用箭头函数方法二:手动绑定 this 完整代码示例使用箭头函数使用 bi…...

d3-contour 生成等高线图
D3.js 是一个强大的 JavaScript 库,用于创建动态、交互式数据可视化。d3-contour 是 D3.js 的一个扩展模块,用于生成等高线图(contour plots)。 属性和方法 属性 x: 一个函数,用于从数据点中提取 x 坐标。y: 一个函…...

Ubuntu20.04离线安装全教程(包括DellR940重置Raid 5、安装Ubuntu、设置root、安装nvidia英伟达显卡驱动及设置防火墙白名单)
本文记录重装Ubuntu20.04的所有记录,从服务器磁盘阵列重新排列、Ubuntu 20.04系统安装、配置root权限、安装Nvidia显卡驱动以及设置防火墙白名单的全部操作。 每一部分参考的博客的出处会放置于段落末尾,表示感谢! 一、重置服务器磁盘阵列&…...

Spring Boot 3 集成 Spring Security(2)授权
文章目录 授权配置 SecurityFilterChain基于注解的授权控制自定义权限决策 在《Spring Boot 3 集成 Spring Security(1)》中,我们简单实现了 Spring Security 的认证功能,通过实现用户身份验证来确保系统的安全性。Spring Securit…...

【开篇】.NET开源 ORM 框架 SqlSugar 系列
01. 前言 ☘️ 1.1 什么是ORM? 对象-关系映射(Object-Relational Mapping,简称ORM),面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对…...
参加面试被问到的面试题
1.在程序中如何开启事务? 在Java中,使用JDBC(Java Database Connectivity)与数据库交互时,你可以使用Connection对象的setAutoCommit方法来控制事务。默认情况下,autoCommit是开启的,这意味着每…...

第29天:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作
时间轴: 演示案例: JS 原生开发-DOM 树-用户交互 DOM:文档操作对象 浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈 安全问题:本身的前端代码通过 DOM 技术实现代码的更新修改ÿ…...
react 的路由功能
1. 安装依赖 pnpm add react-router-dom 2. 基本的路由设置(BrowserRouter) 在 main.tsx 入口文件中使用BrowserRouter组件来包裹整个应用。它会监听浏览器的 URL 变化。 import { StrictMode } from "react";import { createRoot } from …...

SurfaceFlinger学习之一:概览
SurfaceFlinger 是 Android 系统中负责合成和显示屏幕内容的关键系统服务,它运行在一个专用的进程中 (system/bin/surfaceflinger)。它的主要职责是将不同应用程序的绘制内容(即窗口或表面)组合起来,通过硬件抽象层(HA…...

Qt关于窗口一直调用paintEvent的踩坑实录
首先看以下代码: void ItemBlockWidget::paintEvent(QPaintEvent *ev) {// 先调用父类的 paintEvent 以执行默认绘制行为QWidget::paintEvent(ev);qDebug()<<"ItemBlockWidget重绘";QStyleOption opt;opt.initFrom(this);QPainter p(this);style()…...
C++11: STL之bind
C11: STL之bind 引言可调用对象的绑定绑定普通函数绑定静态函数绑定类成员函数绑定仿函数绑定Lambda 占位符std::placeholders的应用嵌套绑定参数重排序结合 STL 算法占位符传递到嵌套函数混合占位符与默认值复杂占位符组合 std::bind的原理std::bind 的设计思路简化实现示例 B…...

在线音乐播放器 —— 测试报告
自动化脚本源代码:Java: 利用Java解题与实现部分功能及小项目的代码集合 - Gitee.com 目录 前言 一、项目简介 1.项目背景 2.应用技术 (1)后端开发 (2)前端开发 (3)数据库 二、项目功能…...
等保测评讲解:安全管理中心
在数字化转型的背景下,网络安全的重要性愈发凸显,而作为中国边疆大省的黑龙江,其网络安全建设更是不可忽视。等保测评,即信息安全等级保护测评,是确保信息系统安全的关键环节。本文将详细讲解黑龙江等保测评中的安全管…...
vue3表单输入相关修饰符使用
在 Vue 3 中,.lazy、.number 和 .trim 是用于 v-model 指令的修饰符,它们可以帮助你在双向绑定时进行特定的处理。 1. .lazy 修饰符 .lazy 修饰符表示只在 input 事件之后触发更新,即输入框的内容发生变化后,只有在用户**失去焦…...

CSS笔记(二)类名复用
这里我通过两张不同位置的卡片来实现效果 代码 <!DOCTYPE html> <html><head><style>/*设置画布*/body{/* 方便排列与对齐*/display: flex; /*画布布满整个窗口*/height: 100vh;/*水平居中*/justify-content: center;/*垂直居中*/align-items: cente…...

TCP三次握手与四次挥手(TCP重传机制,2MSL)超详细!!!计算机网络
本篇是关于3次握手和四次挥手的详细解释~ 如果对你有帮助,请点个免费的赞吧,谢谢汪。(点个关注也可以!) 如果以下内容需要补充和修改,请大家在评论区多多交流~。 目录 1. TCP头部: 2. 三次握手…...

LCR 006. 两数之和 II - 输入有序数组
一.题目: LCR 006. 两数之和 II - 输入有序数组 - 力扣(LeetCode) 二.我的原始解法-暴力解法超时: class Solution: def twoSum(self, numbers: List[int], target: int) -> List[int]: # 暴力解法 result [] for i in rang…...

网络安全在现代企业中的重要作用
网络安全是这个数字时代最令人担忧的事情之一。对技术的依赖性越来越强,使其同时面临多种网络威胁。其声誉和法律后果的大幅下降可能归因于一次妥协。 这使得良好的网络安全成为所有企业的选择和必需品。本文介绍了网络安全的重要性、企业中常见的网络威胁以及公司…...
关于 EKS Bottlerocket AMI 版本与 Karpenter 配置的说明
问题1: Bottlerocket AMI 版本问题 之前,后端团队发现在使用 Bottlerocket v1.26.2 AMI 版本时,存在某些问题。经过 Bottlerocket 团队调查,此行为是罕见的 race condition 导致的结果。 我们在环境中重现了此状况,并且关注到由于 kubelet device manager 的启动时间晚于 NVI…...

Python实现人生重开模拟器
目录 人生重开模拟器介绍 代码实现 打印初始界面 设置初始属性 设置角色性别 设置角色出生点 针对每一岁,生成人生经历 完整代码 人生重开模拟器介绍 人生重开模拟器 是之前比较火的一个小游戏,我们这里使用 Python 实现一个简化版的 人生重开模…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
linux设备重启后时间与网络时间不同步怎么解决?
linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...