【鸿蒙】鸿蒙开发过程中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 实现一个简化版的 人生重开模…...
java——Spring Boot的配置加载顺序和优先级
Spring Boot的配置加载顺序和优先级是确定应用程序如何读取和应用配置的关键。以下是对Spring Boot配置加载顺序和优先级的详细解释: 一、配置加载顺序 命令行参数: Spring Boot会首先加载命令行中指定的参数。这些参数可以通过在命令行中使用--keyval…...
【21-30期】Java技术深度剖析:从分库分表到微服务的核心问题解析
🚀 作者 :“码上有前” 🚀 文章简介 :Java 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 文章题目:Java技术深度剖析:从分库分表到微服务的核心问题解析 摘要: 本…...
CSS:怎么把网站都变成灰色
当大家看到全站的内容都变成了灰色,包括按钮、图片等等。这时候我们可能会好奇这是怎么做到的呢? 有人会以为所有的内容都统一换了一个 CSS 样式,图片也全换成灰色的了,按钮等样式也统一换成了灰色样式。但你想想这个成本也太高了…...
开发一个基于MACOS M1/2芯片的Android 12的模拟器
产品需求:MuMu模拟器Pro_率先适配Apple M系列芯片的安卓模拟器 苹果M芯片专属:产品专为苹果M系列芯片设计,意味着它需要能够充分利用M系列芯片的性能优势。 安卓模拟器:产品是一个安卓模拟器,允许用户在Mac设备上运行…...
Flink 中 JDBC Connector 使用详解
1. 背景 在实时计算或离线任务中,往往需要与关系型数据库交互,例如 MySQL、PostgreSQL 等。Apache Flink 提供了 JDBC Connector,可以方便地将流式数据写入或读取数据库。 本文将介绍 Flink JDBC Connector 的基础用法、配置方法以及注意事…...
【Linux打怪升级记 | 报错02】-bash: 警告:setlocale: LC_TIME: 无法改变区域选项 (zh_CN.UTF-8)
🗺️博客地图 📍1、报错发现 📍2、原因分析 📍3、解决办法 📍4、测试结果 1、报错发现 装好了CentOS操作系统,使用ssh远程登陆CentOS,出现如下告警信息: bash: 警告:setlocale…...
未来已来?AI技术革新改变我们的生活
在21世纪的今天,人工智能(AI)不再是一个遥远的概念,而是逐渐渗透到我们生活的方方面面。从智能家居到自动驾驶汽车,从个性化推荐系统到医疗诊断辅助,AI技术正在以惊人的速度发展,并深刻地影响着…...
【Linux】进程的生命之旅——诞生、消逝与守候(fork/exit/wait)
🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 一念既出,万山无阻 目录 📖一、进程创建 1.fork函数 📚高层封装特性 📚fork返回值 2.写时拷…...
使用vcpkg自动链接tinyxml2时莫名链接其他库(例如boost)
使用vcpkg自动链接tinyxml2时莫名链接其他库(例如boost) vcpkg的自动链接功能非常方便,但在某些情况下会出现过度链接的问题。 链接错误症状 以tinyxml2为例,程序中调用tinyxml2的函数后,若vcpkg中同时存在opencv和…...
【去毛刺】OpenCV图像处理基础:腐蚀与膨胀操作入门
在数字图像处理中,形态学操作是一种常用的技术,用于提取图像中的特定形状或特征。其中,腐蚀(Erosion)和膨胀(Dilation)是两种基本的形态学运算。本文将通过一个简单的例子来演示如何使用Python中…...
住房和城乡建设部课题网站/企业网站设计规范
引入新功能之后,用户可以在VR空间打开手机Android App,比如游戏、工具和App。这些App会漂浮在虚拟大屏幕上,可以用标准的Daydream指点控制器控制,这样一来,开发者如果制作App,没有必要开发新UI,…...
如何在对方网站上做外链/semantics
一、源码特点 asp.net数码销售仓库管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 下载地址: asp.net数码销售仓库管理系统VS开发sqlserver数据库web结构C#编程-电子政务文档类资源-…...
广东品牌网站建设报价/国内销售平台有哪些
POSIX 多线程程序设计 目录表 摘要 译者序Pthreads 概述 什么是线程? 什么是Pthreads? 为什么使用Pthreads? 使用线程设计程序 Pthreads API编译多线程程序 线程管理 创建和终止线程 向线程传递参数 连接(Joining)和分离&#x…...
求做图的网站/百度图片搜索引擎
一 ArrayList ArrayList结构为动态数组,当元素数量达到一定规模,将发生扩容操作,时间复杂度为O(N) 和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多…...
国建设委员会网站上查询/精准营销及推广
工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 系统定义 工程项目管理企业不直接与该工程项目的总承包企…...
做民宿最大的网站/最好的关键词排名优化软件
自从4月18号自走棋推出测试后,短短的一星期,各种玩法攻略层出不穷,安卓玩家玩的开心,苹果用户看着伤心。只能加紧对制作团队的催促。可是,IOS用户其实也可以体验到自走棋手游的乐趣的,只是你还没有找到对的…...