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

如何通过localStorage将带封装私有属性的对象传递到另一个标签页

问题根因

你遇到序列化后为空对象的核心原因是:当前定义的User类通过闭包存储私有属性,私有变量没有挂载到实例的this对象上。而JSON.stringify只会序列化实例自身的可枚举非函数属性,你挂载到this上的只有get/set方法,函数在JSON序列化时会被直接忽略,因此最终输出是空对象。

不存在仅靠getter方法就自动完成序列化的方案,闭包私有变量对外不可访问,必须主动调用get方法读取值才能完成序列化,下面是两种可直接落地的实现方式:


方案实现

方案1:在类内自定义toJSON方法(侵入性最低,推荐)

JSON.stringify执行时会自动调用目标对象的toJSON方法,你只需要在User类中补充这个方法即可,原有构造逻辑完全不用修改:

class User {
  constructor(username, password, email) {
    let _username = '';
    let _password = '';
    let _email = '';

    this.setUsername = username => {
      if (!username) {
        throw new Error("用户名不能为空!");
      }
      _username = username;
    };
    this.getUsername = () => _username;

    this.setPassword = password => {
      if (!password) {
        throw new Error("密码不能为空!");
      }
      _password = password;
    };
    this.getPassword = () => _password;

    this.setEmail = email => {
      if (!email) {
        throw new Error("邮箱地址不能为空!");
      }
      _email = email;
    }
    this.getEmail = () => _email;

    this.setUsername(username || '');
    this.setPassword(password || '');
    this.setEmail(email || '');
  }

  // 新增toJSON方法,定义序列化输出的内容
  toJSON() {
    return {
      username: this.getUsername(),
      password: this.getPassword(),
      email: this.getEmail()
    }
  }
}

存储与恢复逻辑

// 向localStorage存储数据
const user = new User('张三', '123456', 'zhangsan@example.com');
localStorage.setItem('user', JSON.stringify(user));

// 其他标签页恢复类实例
const rawUserData = JSON.parse(localStorage.getItem('user'));
const restoredUser = new User(rawUserData.username, rawUserData.password, rawUserData.email);

恢复后的restoredUser和原始实例完全一致,所有校验逻辑、get/set方法都可以正常使用。


方案2:不修改类定义,手动序列化

如果你不能修改原有User类的代码,可以在序列化时主动调用get方法构造纯数据对象:

// 序列化存储
const user = new User('张三', '123456', 'zhangsan@example.com');
const serializableData = {
  username: user.getUsername(),
  password: user.getPassword(),
  email: user.getEmail()
};
localStorage.setItem('user', JSON.stringify(serializableData));

// 反序列化恢复逻辑和方案1完全一致
const rawUserData = JSON.parse(localStorage.getItem('user'));
const restoredUser = new User(rawUserData.username, rawUserData.password, rawUserData.email);

补充说明
  • localStorage只能存储字符串,天然不支持序列化函数、闭包等JS特有特性,因此跨标签页传递类实例的标准做法就是传递纯状态数据,接收端重新实例化,既不会丢失类的原有特性,也符合存储规则。
  • 密码属于敏感信息,不建议明文存储在localStorage中,实际使用时建议对敏感字段做加密处理后再存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 11:06:02