You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript含类继承与数组的结构序列化问题:数组丢失及three.js对象处理

解决JavaScript类继承结构的数组序列化丢失问题及Three.js对象序列化方案

一、当前代码的问题分析

你遇到的数组“丢失”,实际根源有两个:

  1. Math.random用法错误:Math.random(0, this.greet.length)是无效写法(Math.random无参数),导致get_greet_random大概率返回null,让你误以为数组没被保留。
  2. 继承类的序列化/反序列化逻辑不严谨:虽然greet是实例自有属性,JSON.stringify会默认序列化,但用Object.assign混合实例和反序列化数据时,可能因初始化顺序导致预期外的覆盖。

二、修复数组序列化丢失的方案

方案1:修正核心逻辑错误+优化反序列化

先修正随机取值代码,再用类静态方法实现更可靠的序列化/反序列化:

class Greet
{
    greet;

    constructor()
    {
        this.greet = [];
    }

    add_greet(new_greet)
    {
        this.greet.push(new_greet);
    }

    get_greet_random()
    {
        if(this.greet.length !== 0)
            // 修正Math.random用法:用乘法取指定范围随机数
            return this.greet[Math.floor(Math.random() * this.greet.length)];
        else
            return null;
    }

    // 父类序列化方法
    toJSON() {
        return {
            greet: [...this.greet] // 浅拷贝数组,避免引用问题
        };
    }

    // 父类反序列化静态方法
    static fromJSON(data) {
        const instance = new Greet();
        instance.greet = data.greet || [];
        return instance;
    }
}

class CheckGreet extends Greet
{
    constructor()
    {
        super();
        this.has_say_greet = false;
    }

    check_if_has_greetings()
    {
        console.log("in check");
        if(this.get_greet_random() != null)
            this.has_say_greet = true;

        return this.has_say_greet;
    }

    // 子类继承并扩展序列化方法
    toJSON() {
        return {
            ...super.toJSON(),
            has_say_greet: this.has_say_greet
        };
    }

    // 子类继承并扩展反序列化静态方法
    static fromJSON(data) {
        const instance = super.fromJSON(data);
        instance.has_say_greet = data.has_say_greet ?? false;
        return instance;
    }
}


// 使用示例
let checkGreet = new CheckGreet();
checkGreet.add_greet("Hello World");

// 序列化
let serialized_data = JSON.stringify(checkGreet);
// 反序列化
let deserialized_data = JSON.parse(serialized_data);
let checkGreet_from_deserialized = CheckGreet.fromJSON(deserialized_data);

console.log(checkGreet_from_deserialized.check_if_has_greetings()); // 现在会输出true

方案2:简化版(无需自定义方法)

如果不想写自定义序列化方法,确保实例属性可枚举,并直接手动赋值:

// 修正Math.random后,序列化时展开实例确保所有自有属性被序列化
let serialized_data = JSON.stringify({...checkGreet});

// 反序列化时先创建实例,再手动覆盖属性
let deserialized_data = JSON.parse(serialized_data);
let checkGreet_from_deserialized = new CheckGreet();
checkGreet_from_deserialized.greet = deserialized_data.greet;
checkGreet_from_deserialized.has_say_greet = deserialized_data.has_say_greet;

三、数组存储Three.js对象的序列化方案

Three.js内置对象(如Mesh、Vector3、Geometry等)自带序列化/反序列化机制,无需手动处理:

序列化Three.js对象数组

// 示例:存储Mesh数组
const greetMeshes = [
    new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()),
    new THREE.Mesh(new THREE.SphereGeometry(), new THREE.MeshBasicMaterial())
];

// 逐个将Three.js对象转为JSON格式
const serializedMeshes = greetMeshes.map(mesh => mesh.toJSON());
// 整体序列化
const serialized_data = JSON.stringify({ greet: serializedMeshes });

反序列化Three.js对象数组

const deserialized_data = JSON.parse(serialized_data);
const loader = new THREE.ObjectLoader();

// 逐个解析JSON为Three.js对象
const restoredMeshes = deserialized_data.greet.map(meshJson => loader.parse(meshJson));

注意:如果是自定义的Three.js扩展对象,需要先注册对应的加载器,否则ObjectLoader无法解析。

内容的提问来源于stack exchange,提问作者stickske

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:10:25