千家信息网

怎么用javascript存储函数

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"怎么用javascript存储函数",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么用javascript存储函数"吧!背景介绍我们都知
千家信息网最后更新 2026年11月02日怎么用javascript存储函数

本篇内容主要讲解"怎么用javascript存储函数",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么用javascript存储函数"吧!

背景介绍

我们都知道要想搭建一个前端页面基本需要如下3个要素:

  • 元素(UI)

  • 数据(Data)

  • 事件/交互(Event)

在 数据驱动视图 的时代, 这三个要素的关系往往如下图所示:

可视化搭建平台的设计思路往往也是基于上面的过程展开的, 我们需要提供编辑器环境给用户来创建视图和交互, 最终用户保存的产物可能是这样的:

{    "name": "Dooring表单",    "bgColor": "#666",    "share_url": "http://xxx.cn",    "mount_event": [        {            "id": "123",            "func": () => {                // 初始化逻辑                GamepadHapticActuator();            },            "sourcedata": []        }    ],    "body": [        {            "name": "header",            "event": [                {                    "id": "123",                    "type": "click",                    "func": () => {                        // 组件自定义交互逻辑                        showModal();                    }                }            ]        }    ]}

那么问题来了, json 字符串我们好保存(可以通过JSON.stringify序列化的方式), 但是如何将函数也一起保存呢? 保存好了函数如何在页面渲染的时候能正常让 js 运行这个函数呢?

实现方案思考

我们都知道将 js 对象转化为json 可以用 JSON.stringify 来实现, 但是它也会有局限性, 比如:

  1. 转换值如果有 toJSON() 方法,那么由 toJson() 定义什么值将被序列化

  2. 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中

  3. 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值

  4. undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined)

  5. 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们

  6. Date 日期调用了 toJSON() 将其转换为了 string 字符串(同Date.toISOString()),因此会被当做字符串处理

  7. NaN 和 Infinity 格式的数值及 null 都会被当做 null

  8. 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性

我们可以看到第4条, 如果我们序列化的对象中有函数, 它将会被忽略! 所以常理上我们使用JSON.stringify 是无法保存函数的, 那还有其他办法吗?

也许大家会想到先将函数转换成字符串, 再用 JSON.stringify 序列化后保存到后端, 最后在组件使用的时候再用 eval 或者 Function 将字符串转换成函数. 大致流程如下:

不错, 理想很美好, 但是现实很_______.

接下来我们就一起分析一下关键环节 func2string 和 string2func 如何实现的.

js存储函数方案设计

熟悉 JSON API 的朋友可能会知道 JSON.stringify 支持3个参数, 第二个参数 replacer 可以是一个函数或者一个数组。作为函数,它有两个参数,键(key)和值(value),它们都会被序列化。 函数需要返回 JSON 字符串中的 value, 如下所示:

  • 如果返回一个 Number, 转换成相应的字符串作为属性值被添加入 JSON 字符串

  • 如果返回一个 String, 该字符串作为属性值被添加入 JSON 字符串

  • 如果返回一个 Boolean, 则 "true" 或者 "false" 作为属性值被添加入 JSON 字符串

  • 如果返回任何其他对象,该对象递归地序列化成 JSON 字符串,对每个属性调用 replacer 方法。除非该对象是一个函数,这种情况将不会被序列化成 JSON 字符

  • 如果返回 undefined,该属性值不会在 JSON 字符串中输出

所以我们可以在第二个函数参数里对 value类型为函数的数据进行转换。如下:

const stringify = (obj) => {    return JSON.stringify(obj, (k, v) => {      if(typeof v === 'function') {          return `${v}`      }      return v    })}

这样我们看似就能把函数保存到后端了. 接下来我们看看如何反序列化带函数字符串的 json.

因为我们将函数转换为字符串了, 我们在反解析时就需要知道哪些字符串是需要转换成函数的, 如果不对函数做任何处理我们可能需要人肉识别.

人肉识别的缺点在于我们需要用正则把具有函数特征的字符串提取出来, 但是函数写法有很多, 我们要考虑很多情况, 也不能保证具有函数特征的字符串一定是函数.

所以我换了一种简单的方式, 可以不用写复杂正则就能将函数提取出来, 方法就是在函数序列化的时候注入标识符, 这样我们就能知道那些字符串是需要解析为函数了, 如下:

stringify: function(obj: any, space: number | string, error: (err: Error | unknown) => {}) {        try {            return JSON.stringify(obj, (k, v) => {                if(typeof v === 'function') {                    return `${this.FUNC_PREFIX}${v}`                }                return v            }, space)        } catch(err) {            error && error(err)        }}

this.FUNC_PREFIX 就是我们定义的标识符, 这样我们在用 JSON.parse 的时候就能快速解析函数了. JSON.parse 也支持第二个参数, 他的用法和 JSON.stringify 的第二个参数类似, 我们可以对它进行转换, 如下:

parse: function(jsonStr: string, error: (err: Error | unknown) => {}) {        try {            return JSON.parse(jsonStr, (key, value) => {                if(value && typeof value === 'string') {                    return value.indexOf(this.FUNC_PREFIX) > -1 ? new Function(`return ${value.replace(this.FUNC_PREFIX, '')}`)() : value                }                return value            })        } catch(err) {            error && error(err)        }    }

new Function 可以把字符串转换成 js 函数, 它只接受字符串参数,其可选参数为方法的入参,必填参数为方法体内容, 一个形象的例子:

我们上述的代码中函数体的内容:

new Function(`return ${value.replace(this.FUNC_PREFIX, '')}`)()

之所以要 return 是为了把原函数原封不动的还原, 大家也可以用 eval , 但是出于舆论还是谨慎使用.

以上方案已经能实现前端存储函数的功能了, 但是为了更工程化和健壮性还需要做很多额外的处理和优化, 这样才能让更多人开箱即用的使用你的库.

最后

为了让更多人能直接使用这个功能, 我将完整版 json 序列化方案封装成了类库,

支持功能如下:

  • stringify 在原生JSON.stringify 的基础上支持序列化函数,错误回调

  • parse 在原生JSON.parse 的基础上支持反序列化函数,错误回调

  • funcParse 将js对象中的函数一键序列化, 并保持js对象类型不变

安装方式如下:

# or npm install xijsyarn add xijs

使用:

import { parser } from 'xijs';const a = {    x: 12,    b: function() {      alert(1)    } }  const json = parser.stringify(a); const obj = parser.parse(json); // 调用方法 obj.b();

到此,相信大家对"怎么用javascript存储函数"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

函数 字符 字符串 序列 对象 参数 属性 方法 存储 支持 内容 数组 方案 时候 功能 数据 方式 更多 类型 过程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡网 百单网互联网科技有限公司怎么样 亿人帮互联网科技有限公司 北京路客互联网科技有限公司 新华互联网科技学校 深圳恒合互联网络科技有限公司 平安科技 互联网 苏州互联网科技贷款公司 科技创新互联网企业 广州善班互联网科技 互联网科技股午盘股票涨跌 湖南诚度互联网科技有限公司 湖北码尼互联网科技有限公司电话 朱啸虎曾投资哪些互联网科技企业 2021互联网科技公司排名 四川互联网展示科技馆设计 互联网科技股为什么大涨 本届互联网大会上的黑科技 下一代互联网重大应用科技园 互联网科技职业技能培训学校 什么是科技互联网 广东猪兼强互联网科技有限公司 西安纸贵互联网科技有限公司 互联网科技公司华为 安徽鑫晟辉互联网科技 互联网前沿科技 荆州市昕露互联网络科技有限公司 互联网科技公司营业执照怎么办理 图游互联网科技 互联网科技平台产品运营
0