如何通过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
相关产品推荐
相关产品推荐

