讲师中心 微信公众号
AI工具推荐 视频效率加速

在纯前端 JavaScript 中实现跨页面持久化的单例模式

秋静酱_1810

秋静酱_1810

发布时间:2026-02-11 20:56:27

|

280人浏览过

|

来源于php中文网

原创

在纯前端 JavaScript 中实现跨页面持久化的单例模式

本文介绍如何在基于 node.js 后端路由 + 多 html 页面的纯前端架构中,通过 localstorage(或 sessionstorage)持久化单例状态,解决页面跳转导致 javascript 模块重初始化、内存状态丢失的问题。

在传统多页应用(MPA)中,每个 HTML 页面(如 /, /login)由后端独立返回(例如 res.sendFile("index.html")),浏览器会完全重新加载整个文档上下文:DOM 重建、脚本重新执行、内存变量清空。这意味着即使你用 IIFE 实现了经典的 JavaScript 单例模式,每次页面跳转后 model.js 都会被重新解析执行,instance 变量重置,所有运行时状态(如 isLogged = true)瞬间丢失——这并非单例失效,而是浏览器导航机制的固有行为。

要实现“跨页面共享状态”,关键不在于阻止 JS 重载,而在于将关键数据脱离内存、持久化到浏览器存储层。localStorage 和 sessionStorage 是最直接、标准且无需服务端配合的解决方案。

✅ 推荐方案:基于 localStorage 的可持久化单例

以下是一个生产就绪的单例实现,已融合最佳实践(自动加载/保存、类型安全初始化、避免函数序列化):

// frontend/model.js
const Model = (function () {
  let instance = null;

  // ✅ 纯数据对象(不可含函数、DOM 引用等无法序列化的值)
  const defaultData = {
    isLogged: false,
    userId: null,
    username: '',
    lastAccessTime: Date.now()
  };

  function init() {
    // 1️⃣ 启动时从 localStorage 加载(若不存在则用默认值)
    const saved = localStorage.getItem('Model');
    const data = saved ? { ...defaultData, ...JSON.parse(saved) } : { ...defaultData };

    // 2️⃣ 返回仅含纯方法的 API 对象(无闭包引用,便于调试)
    return {
      getIsLogged() {
        return data.isLogged;
      },
      setIsLogged(value) {
        data.isLogged = Boolean(value);
      },
      getUserId() {
        return data.userId;
      },
      setUserId(id) {
        data.userId = id;
      },
      getUsername() {
        return data.username;
      },
      setUsername(name) {
        data.username = String(name).trim();
      },
      // 3️⃣ 显式保存方法(调用方负责时机控制)
      save() {
        localStorage.setItem('Model', JSON.stringify(data));
      },
      // 4️⃣ 可选:强制同步刷新(用于调试或紧急恢复)
      reload() {
        const saved = localStorage.getItem('Model');
        if (saved) Object.assign(data, JSON.parse(saved));
      }
    };
  }

  return {
    getInstance() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  };
})();

// ✅ 使用示例(在任意 HTML 页面中)
document.addEventListener('DOMContentLoaded', () => {
  const model = Model.getInstance();

  // 登录成功后更新并保存
  function handleLoginSuccess(user) {
    model.setIsLogged(true);
    model.setUserId(user.id);
    model.setUsername(user.name);
    model.save(); // ? 关键:立即持久化
    window.location.href = '/'; // 跳转
  }

  // 页面加载时读取最新状态(无需手动 reload)
  console.log('当前登录状态:', model.getIsLogged()); // true / false
});

⚠️ 重要注意事项

  • localStorage vs sessionStorage

    立即学习“Java免费学习笔记(深入)”;

    java后端编程
    java后端编程

    专用于 Java Spring Boot 后端开发的专业技能。当用户提出以下需求时,应调用此技能:构建 REST API、创建 Spring Boot 项目、编写 Java 后端服务、配置数据库访问(JPA / MyBatis)、处理认证与授权(Spring Security / JWT)、实现微服务架构(Spring Cloud)、排查 Spring Boot 相关错误、审查 Java 代码质量,或执行任何与 Spring Boot / Java 后端相关的任务。

    下载
    • localStorage:数据永存(除非手动清除或代码删除),适合长期状态(如用户偏好、登录令牌)。
    • sessionStorage:仅限当前标签页生命周期,关闭标签即销毁。更推荐用于登录态,因其天然契合“一次会话”语义,且避免服务端重启后旧缓存干扰(如问题中提到的 HTML 片段 stale 问题)。只需将 localStorage 替换为 sessionStorage 即可切换。
  • 数据序列化限制
    JSON.stringify() 会忽略函数、undefined、Symbol、循环引用。务必确保 data 对象只包含原始类型(string/number/boolean/null)、数组或扁平对象。复杂状态请先解构再存。

  • 保存时机决定一致性
    save() 必须在状态变更后显式调用(如登录后、登出后、配置修改后)。不要依赖 beforeunload(可能被阻塞或失败),而应在业务逻辑关键路径中主动触发。

  • 安全性提醒
    localStorage 可被前端脚本任意读写,绝不存储敏感凭证(如密码、原始 token)。应仅存标识性信息(如 userId, isLogged),敏感操作始终由后端校验。

✅ 进阶建议

  • 封装存储层:将 localStorage 操作抽象为 StorageManager 类,支持 fallback(如内存兜底)、加密、过期时间。
  • 事件驱动同步:监听 storage 事件,在同域其他标签页中自动响应状态变更(实现多标签页协同)。
  • 与现代框架集成:若后续升级为 SPA(如 Vue/React),此单例可无缝转为 Pinia/Vuex 或 Context Provider 的底层状态源。

通过将单例的“状态载体”从易失的内存迁移至浏览器持久化存储,你就能在纯前端 MPA 架构中稳健地实现跨页面共享状态——无需改造后端路由,不依赖 Cookie 或服务端 Session,真正践行“前端自治”。

热门AI工具

更多
火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2155

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3322

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1116

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3819

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6499

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

2130

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

163

2025.11.30

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn