HarmonyOS 鸿蒙Next:将一个JSON.parse()直接或利用as等方式解析成对象时,若JSON对象赋给class,会删除class预先定义的属性和方法

发布于 1周前 作者 yibo5220 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:将一个JSON.parse()直接或利用as等方式解析成对象时,若JSON对象赋给class,会删除class预先定义的属性和方法

cke_151.png

export class Point {
  x: number = 20;
  y: number = 5;

  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }

  getX(i?: number): number {
    if (typeof i === 'undefined') {
      return this.x
    } else {
      return this.x + i
    }
  }
}

@Entry
@Component
struct Page36 {
  build() {
    Column() {
      Button('点击测试').onClick(() =>{
        // 使用示例
        console.log('输出:' + new Point(3, 2).getX()); // 输出: 3
        console.log('输出:' + new Point(3, 2).getX(123)); // 输出: 126

        let jsonStr = `
          {
              "x":3
          }
        `
        let myPoint :Point = JSON.parse(jsonStr)
        console.log('输出x:' + myPoint.x); // 输出: 3
        console.log('输出y:' + myPoint.y); // 输出:undefined
        try{
          console.log('输出:' + myPoint.getX());
        }catch (e){
          console.error(JSON.stringify(e))//异常{}
        }
        try{
          console.log('输出:' + myPoint.getX(123));
        }catch (e){
          console.error(JSON.stringify(e))//异常{}
        }
      })
    }
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next:将一个JSON.parse()直接或利用as等方式解析成对象时,若JSON对象赋给class,会删除class预先定义的属性和方法的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

16 回复

更多关于HarmonyOS 鸿蒙Next:将一个JSON.parse()直接或利用as等方式解析成对象时,若JSON对象赋给class,会删除class预先定义的属性和方法的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我认为这个有点坑的地方就在于,其中一个属性y定义的是number,哪怕是没有赋值,我也是认为y默认应该为5,结果就是为undefined。这个就意味着我使用数据的时候,并不知道那个数据是安全的,导致不知道坑在什么地方。

二是现在鸿蒙加了很多校验,尤其是类型方面的,结果发现更像是伪校验,如果校验严格,其实不应该让这样的事情发生的,哪怕是TS的特性也不行,就是我自己不使用JSON生成对象,也不能保证第三方不使用,就是对于我个人来说,只要不是我自己通过new创建的对象都是不安全的,这样可能性就太多了。

幸运的是,我发现并采用了class-transformer库中的plainToClassFromExist方法,这一策略显著改善了数据处理流程。通过先实例化类并利用该方法将JSON数据无缝填充到现有对象中,我不仅确保了遵循类定义的属性和方法结构,还高效规避了手动转换可能导致的遗漏或类型错误。这种方法论在面对复杂接口返回的海量数据时尤为重要,它像一座桥梁,连接了原始数据与预期对象模型,确保了应用的健壮性,避免了潜在的崩溃风险,提升了用户体验和开发效率。

找HarmonyOS工作还需要会Flutter技术的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

class-transformer 这是一个不错的东西。但是一个要形成协议或者是规定才有保障,否则像我之前说的,我能保证我自己的项目的使用正常,但是其他的第三方呢?这样的话就会导致集成第三方的难度或者是复杂度大大增加了,要了解下,其实作为开发人员,每个人的水平都是不一样的,这个时候希望通过自己的自觉去约束,这个有点抽象了。能够通过程序或者是机器去约束的东西,千万别靠人。只要有电的情况下,机器或者程序比人可靠太多了。

我看了一下API 12的文档,发现鸿蒙自己封装了一个JSON。使用时需要 import JSON from '@ohos.util.json'; 我试着创建了一个API 12的项目,运行报错提示不支持预览器,但我又没对应的真机和模拟器,感觉将来升级又是一个坑。🤣,

个人理解:

JSON.parse() 生成一个对象,占用某个内存空间,赋值具体类型变量时将生成对象与类型的数据结构挂钩,但生成对象所用内存中并无 类成员中未对应上的属性或方法的位置,所以赋值过程仅是个映射存在的属性的过程,并未新建一个类对象并将可映射属性转移过去;对象在内存中存储时,成员方法应该是以一个指针(指向函数在内存的位置)保存在对象占用的内存空间中;

所以,赋值操作应当只是没有重构整个对象,而非删除对象应有的属性和方法。不过这个发现很有意义,写代码时不能想当然以为解析后赋值就能当正常对象用了。试了进行 as Point 和 <Point> 强制转换,效果依旧。

当使用JSON.parse()JSON字符串解析为TypeScript对象时,它只会还原JSON字符串中的属性和值,并不会还原方法。

找到了一个第三方库class-transformer,用plainToClassFromExist()可以。

https://developer.huawei.com/consumer/cn/forum/topic/0202149451978737371?fid=0109140870620153026

但是这个转数组的时候感觉不好使啊 你试过吗

我这边的需求,只要最外层是对象就行,里面的数组都可以被转换。目前项目就在用,没出现啥问题。

再细看了一下JSON接口,我发现 parse() 方法有个 reviver 可选参数,是个函数参数,看上去是用于对解析数据进行再次处理;所以如果希望得到完全的类对象,可在此进行对象构建,并将解析数据一一对应到对象中后再返回,这样应该就可得到正常类对象了。

在HarmonyOS鸿蒙Next环境中,当你使用JSON.parse()解析JSON字符串并将其结果直接赋值给一个类的实例,或者通过as关键字转换为某个类的类型时,确实可能会遇到类预先定义的属性和方法被覆盖或“删除”的情况。这通常是因为JSON解析的结果是一个普通的JavaScript对象(在鸿蒙中可能是对应的对象类型),它不具备目标类中的非枚举属性或方法。

为了解决这个问题,你需要采用一种方法,确保JSON解析后的对象与你的类实例能够正确合并,而不是直接覆盖。以下是一种可能的实现思路:

  1. 创建一个新的类实例。
  2. 遍历JSON解析后的对象属性。
  3. 使用反射或类似的机制(鸿蒙可能提供特定的API),将属性逐一赋值给类实例,同时避免覆盖类原有的属性和方法。

请注意,这种方法可能需要根据鸿蒙的具体API和框架进行调整。如果鸿蒙提供了特定的数据处理或对象映射库,使用这些库可能是更简洁和安全的解决方案。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部