0

0

深入理解JavaScript中函数赋值与JSON.stringify的行为

聖光之護

聖光之護

发布时间:2025-10-04 11:42:39

|

285人浏览过

|

来源于php中文网

原创

深入理解JavaScript中函数赋值与JSON.stringify的行为

本文旨在阐明JavaScript中函数赋值给对象属性的正常机制,并重点解析JSON.stringify在处理函数时的特殊行为。核心内容是,函数可以被成功赋值给对象,但JSON.stringify在序列化过程中会跳过函数类型的属性,导致其在JSON字符串中缺失,但这并非函数赋值失败,而是JSON.stringify的预期设计。

JavaScript中函数作为对象属性

javascript中,函数是第一类公民,这意味着它们可以像其他任何值(如字符串、数字或布尔值)一样被赋值给变量、作为参数传递、从函数中返回,以及作为对象的属性。将一个函数赋值给一个对象的属性是完全合法的操作,并且是javascript中常见的编程模式,例如在定义对象方法或事件处理函数时。

考虑以下示例代码片段,它尝试在一个循环中创建函数并将其赋值给一个对象:

export function generate_api_calls(app_name) {
  let api_calls = {}
  api_calls['cameraFeed'] = `http://${hostname}:${camera_port}${CAMERA_FEED_URL}`

  let ff
  let items = [1, 2, 3, 4]
  for (let i in items) {
    let name = items[i]
    function bar(j) {
      logger.info(`bar ${j}`)
    };

    bar(i) // 函数在此处被成功调用
    ff = bar // 函数被成功赋值给变量 ff
    api_calls[name] = bar; // 函数被赋值给 api_calls 对象的属性
    logger.info(`generate_api_calls api ${name} ${JSON.stringify(api_calls)}`)
    logger.info(`generate_api_calls api ${JSON.stringify(api_calls[name])}`)
  }
  ff('00'); // 通过 ff 变量成功调用函数

  logger.info(`generate_api_calls 5 ${JSON.stringify(api_calls)}`)
  return api_calls
}

从上述代码的执行日志中可以看到,bar(i) 和 ff('00') 都成功执行,这表明函数 bar 被正确创建并赋值给了 ff 变量。同样,当 api_calls[name] = bar; 执行时,函数 bar 确实被赋值给了 api_calls 对象的对应属性。

然而,日志中 logger.info(generate_api_calls api ${JSON.stringify(api_calls[name])}) 输出 undefined,并且 JSON.stringify(api_calls) 的结果中也看不到被赋值的函数,这让开发者误以为函数赋值失败。这并非JavaScript的"bug",而是与JSON.stringify的特定行为有关。

JSON.stringify的工作原理与局限性

JSON.stringify() 是JavaScript中用于将JavaScript值转换为JSON字符串的内置方法。它遵循JSON数据格式规范,该规范对可序列化的数据类型有明确的规定。

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

JSON.stringify可以序列化的数据类型包括:

  • 对象 (Object): 纯粹的JavaScript对象(字面量对象 {}),其可枚举的自身属性会被序列化。
  • 数组 (Array): 数组中的所有元素都会被序列化。
  • 字符串 (String): 字符串值。
  • 数字 (Number): 数字值。
  • 布尔值 (Boolean): true 或 false。
  • null: null 值。

JSON.stringify不会序列化的数据类型:

LongShot
LongShot

LongShot 是一款 AI 写作助手,可帮助您生成针对搜索引擎优化的内容博客。

下载
  • 函数 (Function): 无论是普通函数、箭头函数还是方法,JSON.stringify都会跳过它们,不会将其包含在最终的JSON字符串中。
  • undefined: 当JSON.stringify遇到undefined值时,如果它是一个对象的属性值,该属性会被跳过;如果它是一个数组元素,该元素会被转换为null。
  • Symbol: Symbol类型的值会被跳过。

因此,当您尝试对一个包含函数的对象进行 JSON.stringify 操作时,这些函数属性会被忽略。如果直接对一个函数本身调用 JSON.stringify,结果将是 undefined。

验证函数赋值的正确性

为了验证函数是否确实被赋值给了对象,而不是仅仅依赖JSON.stringify的输出,我们可以直接访问该属性或检查其类型。

以下是修改后的代码片段,展示了如何正确验证函数赋值:

const logger = {
  info: console.log, // 简化logger以直接输出到控制台
};

function generate_api_calls(app_name) {
  let api_calls = {};

  api_calls['cameraFeed'] = 'cameraFeed'; // 简化URL

  let ff;
  let items = [1, 2, 3, 4];
  for (let i in items) {
    let name = items[i];

    function bar(j) {
      logger.info(`bar ${j}`);
    };

    bar(i); // 确认函数可调用
    ff = bar; // 确认函数可赋值给变量
    api_calls[name] = bar; // 函数被赋值给对象属性

    // 关键验证点:直接打印对象属性,而不是其JSON字符串化结果
    console.log('watch me printing function --->', api_calls[name]); 
    console.log('watch me printing typeof function --->', typeof api_calls[name]); // 检查类型

    logger.info(`generate_api_calls api ${name} ${JSON.stringify(api_calls)}`); // 再次观察 JSON.stringify 的行为
    logger.info(`generate_api_calls api ${JSON.stringify(api_calls[name])}`); // 对函数进行 JSON.stringify 的结果
  }
  ff('00'); // 确认通过 ff 变量函数可调用

  // 关键验证点:直接打印整个 api_calls 对象
  console.log('watch me printing api_calls --->', api_calls);

  logger.info(`generate_api_calls 5 ${JSON.stringify(api_calls)}`); // 最终的 JSON.stringify 结果
  return api_calls
}

generate_api_calls('test');

// 额外示例:展示 JSON.stringify 忽略函数的行为
console.log('JSON.stringify with function:', JSON.stringify({
  data: 'abc',
  func: () => {},
  undef: undefined
})); // 输出 {"data":"abc"}

运行上述代码,您会观察到 console.log('watch me printing function --->', api_calls[name]); 会打印出函数本身的定义,而 console.log('watch me printing typeof function --->', typeof api_calls[name]); 会打印 function。这明确地证明了函数已被成功赋值。

总结与注意事项

  1. 函数赋值正常: 在JavaScript中,将函数赋值给对象属性是完全支持且正常工作的。您所遇到的并非JavaScript语言的“bug”。
  2. JSON.stringify的特性: JSON.stringify在序列化过程中会跳过函数 (function) 和 undefined 类型的值。这意味着,即使函数已成功赋值给对象属性,它们也不会出现在 JSON.stringify 的输出结果中。直接对函数本身进行 JSON.stringify 会返回 undefined。
  3. 正确调试方法: 在调试时,如果需要检查对象是否包含函数,请直接使用 console.log(myObject.myFunction) 或 console.log(typeof myObject.myFunction),而不是依赖 JSON.stringify 的输出。
  4. 用途考量: JSON.stringify 主要用于数据交换,而函数通常不属于可交换的数据。如果确实需要序列化函数(例如,将其作为字符串存储),则需要手动将其转换为字符串(例如 func.toString()),但这通常不推荐,因为它涉及在接收端使用 eval() 或 new Function(),这可能带来安全风险和性能问题。

通过理解 JSON.stringify 的这些基本行为,可以避免在JavaScript开发中因其特性而产生的困惑。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

419

2023.08.07

json是什么
json是什么

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

535

2023.08.23

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

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

311

2023.10.13

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

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

77

2025.09.10

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

309

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

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

463

2023.08.02

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

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

350

2023.11.13

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号