JavaScript中的常量值与引用值:从基础到实践
JavaScript中的常量值与引用值:从基础到实践
在JavaScript中,常量值(原始值)和引用值(对象值)是两种核心的数据类型。它们的存储方式、行为特性以及使用场景存在显著差异,理解这些差异对于编写高效、稳定的代码至关重要。本文将深入浅出地解析这两类值的概念、使用技巧、应用场景及注意事项。
一、常量值与引用值的概念
1. 常量值(原始值)
常量值是JavaScript中最简单的数据类型,直接存储在内存的栈(Stack)中。它们的值是不可变的(Immutable),即一旦创建,值的内容无法被修改。常见的原始值包括:
- 数字(Number):如
3.14
、42
- 字符串(String):如
'Hello World'
- 布尔值(Boolean):
true
或false
null
:表示空值undefined
:表示未定义的值- Symbol(ES6新增):唯一的标识符
特点:
- 直接存储在栈中,访问速度快。
- 赋值时会创建副本,两个变量之间互不影响。
示例:
let a = 10;
let b = a; // b 是 a 的副本
a = 20;
console.log(a); // 20
console.log(b); // 10(b 的值未受影响)
2. 引用值(对象值)
引用值是更复杂的数据类型,存储在内存的堆(Heap)中。它们的值是可变的(Mutable),变量存储的是指向堆内存地址的引用(Reference)。常见的引用值包括:
- 对象(Object):如
{ name: 'Alice' }
- 数组(Array):如
[1, 2, 3]
- 函数(Function):如
function() { ... }
- Date、RegExp、Map、Set 等内置对象
特点:
- 存储在堆中,变量保存的是引用地址。
- 赋值时复制引用地址,多个变量共享同一个对象。
示例:
let obj1 = { name: 'Alice' };
let obj2 = obj1; // obj2 指向 obj1 的地址
obj1.name = 'Bob';
console.log(obj1.name); // Bob
console.log(obj2.name); // Bob(obj2 的值也被修改)
二、使用技巧
1. 常量值的使用
- 不可变性:原始值的不可变性使其适用于存储固定数据,例如数学常数、配置参数等。
- 性能优化:由于原始值直接存储在栈中,访问速度更快,适合频繁读取的场景。
示例:
// 使用 const 声明常量
const PI = 3.14159;
const MAX_USERS = 100;// 直接使用常量值
function calculateArea(radius) {return PI * radius * radius;
}
2. 引用值的使用
- 共享状态:引用值适合需要共享状态的场景,例如组件间通信、状态管理等。
- 动态修改:通过引用地址直接操作对象或数组的属性/元素,避免重复创建新对象。
示例:
// 使用对象存储用户信息
const user = { name: 'Alice', age: 25 };// 修改用户信息
user.age = 26;
console.log(user.age); // 26// 动态扩展对象属性
user.email = 'alice@example.com';
console.log(user.email); // alice@example.com
三、应用场景
1. 常量值的应用场景
- 数学计算:存储固定数值(如圆周率、税率等)。
- 配置参数:定义全局常量(如最大用户数、超时时间等)。
- 逻辑判断:用于布尔值的条件判断(如
if (isLogin) { ... }
)。
示例:
// 配置参数
const API_URL = 'https://api.example.com';// 数学计算
function calculateTax(amount) {const TAX_RATE = 0.08;return amount * (1 + TAX_RATE);
}
2. 引用值的应用场景
- 数据集合:存储和操作复杂数据结构(如数组、对象)。
- 状态管理:维护应用的状态(如用户信息、购物车数据)。
- 函数参数传递:传递大型对象或数组时,避免复制开销。
示例:
// 状态管理
const cart = { items: [], totalPrice: 0 };// 添加商品到购物车
function addToCart(item, price) {cart.items.push(item);cart.totalPrice += price;
}addToCart('Apple', 1.99);
console.log(cart); // { items: ['Apple'], totalPrice: 1.99 }
四、注意事项
1. 常量值的注意事项
- 不可变性陷阱:尝试修改原始值会导致新值被创建,而不会影响原值。
- 避免魔法数字:不要直接在代码中使用硬编码的数字或字符串,而是通过常量命名提高可读性。
错误示例:
// 错误:直接使用魔法数字
if (user.role === 1) {// ...
}// 正确:使用常量命名
const ROLE_ADMIN = 1;
if (user.role === ROLE_ADMIN) {// ...
}
2. 引用值的注意事项
- 浅拷贝问题:直接赋值引用值会导致共享同一对象,修改一个变量会影响另一个变量。
- 深拷贝解决方案:需要复制引用值时,使用深拷贝方法(如
JSON.parse(JSON.stringify(obj))
、lodash.cloneDeep
等)。
示例:
// 浅拷贝问题
const obj1 = { name: 'Alice' };
const obj2 = obj1;
obj2.name = 'Bob';
console.log(obj1.name); // Bob(obj1 的值也被修改)// 深拷贝解决方案
const obj3 = JSON.parse(JSON.stringify(obj1));
obj3.name = 'Charlie';
console.log(obj1.name); // Bob(obj1 的值未受影响)
3. const
的注意事项
- 引用值的
const
声明:const
保证变量的引用地址不可变,但对象内容可以修改。 - 避免误用:如果需要完全禁止修改对象内容,需结合
Object.freeze()
方法。
示例:
// const 声明引用值
const user = { name: 'Alice' };
user.name = 'Bob'; // 合法:修改对象属性
user = { name: 'Charlie' }; // 报错:重新赋值// 冻结对象内容
const frozenUser = Object.freeze({ name: 'Alice' });
frozenUser.name = 'Bob'; // 静默失败(严格模式下抛出错误)
五、总结
JavaScript中的常量值和引用值是构建复杂应用的基础。理解它们的存储方式、行为特性和使用场景,能够帮助开发者写出更高效、更健壮的代码。以下是关键点总结:
特性 | 常量值(原始值) | 引用值(对象值) |
---|---|---|
存储位置 | 栈(Stack) | 堆(Heap) |
不可变性 | 是 | 否(对象内容可变) |
赋值行为 | 复制值 | 复制引用地址 |
适用场景 | 固定数据、配置参数 | 复杂数据、状态管理 |
注意事项 | 避免魔法数字 | 注意浅拷贝和深拷贝问题 |
在实际开发中,合理使用 const
和 let
声明变量,结合深拷贝技术,可以有效避免因引用值共享导致的意外修改。掌握这些核心概念,是成为JavaScript高级开发者的关键一步。
相关文章:
JavaScript中的常量值与引用值:从基础到实践
JavaScript中的常量值与引用值:从基础到实践 在JavaScript中,常量值(原始值)和引用值(对象值)是两种核心的数据类型。它们的存储方式、行为特性以及使用场景存在显著差异,理解这些差异对于编写…...

港大NVMIT开源Fast-dLLM:无需重新训练模型,直接提升扩散语言模型的推理效率
作者:吴成岳,香港大学博士生 原文:https://mp.weixin.qq.com/s/o0a-swHZOplknnNxpqlsaA 最近的Gemini Diffusion语言模型展现了惊人的throughput和效果,但是开源的扩散语言模型由于缺少kv cache以及在并行解码的时候性能严重下降等…...

ESP32-C3 Vscode+ESP-IDF开发环境搭建 保姆级教程
1.背景 最近esp32的芯片很火,因为芯片自带了WIFI和BLE功能,是物联网项目开发的首选芯片,所以,我也想搞个简单的esp32芯片试试看。于是,我设计了一个简单的板子。如下 这块板子很简单,主要的电路来自于乐鑫…...
SCSS 全面深度解析
一、SCSS 入门指南:为你的 CSS 工作流注入超能力 在现代 Web 开发中,样式表的复杂性和维护成本日益增加。为了应对这一挑战,CSS 预处理器应运而生,而 SCSS (Sassy CSS) 正是其中最流行、最强大的工具之一。本指南将带你深入了解 …...

解决vscode打开一个单片机工程文件(IAR/keil MDK)因无法找到头文件导致的结构体成员不自动补全问题。
最近一直在用vscode安装c/c插件后编辑STM32标准库(keil MDK)项目源文件,因为我感觉vscode在代码编辑方面比keil MDK本身优秀太多。发现打开工程后,结构体变量的成员在输入“.”后不自己弹出的问题,后来查找各方资料&am…...
Python 在金融中的应用- Part 1
早在2018年,我开始对资本市场产生兴趣。理解资本市场的基本理论对财富积累至关重要。我开始阅读所有经典著作,如《聪明的投资者》和《证券分析》。在这一系列文章中,我想与读者分享在Python编程语言背景下理解金融理论的旅程。在文章的第一大部分,我们将专注于金融模型的线…...

【Node.js 深度解析】npm install 遭遇:npm ERR! code CERT_HAS_EXPIRED 错误的终极解决方案
目录 📚 目录:洞悉症结,精准施治 🔍 一、精准剖析:CERT_HAS_EXPIRED 的本质 🕵️ 二、深度溯源:证书失效的 N 重诱因 💡 三、高效解决策略:六脉神剑,招招…...

Vue内置组件Teleport和Suspense
一. Vue内置组件Teleport 认识Teleport( teleport:允许我们把组件的模板渲染到特定的元素上) 1.1. 在组件化开发中,我们封装一个组件A,在另外一个组件B中使用 组件A中template的元素,会被挂载到组件B中template的某个位置…...

Java网络编程实战:TCP/UDP Socket通信详解与高并发服务器设计
🔍 开发者资源导航 🔍🏷️ 博客主页: 个人主页📚 专栏订阅: JavaEE全栈专栏 内容: socket(套接字)TCP和UDP差别UDP编程方法使用简单服务器实现 TCP编程方法Socket和ServerSocket之间的关系使用简…...

vue+threeJs 绘制3D圆形
嗨,我是小路。今天主要和大家分享的主题是“vuethreeJs 绘制圆形”。 今天找到一个用three.js绘制图形的项目,主要是用来绘制各种形状。 项目案例示意图 1.THREE.ShapeGeometry 定义:是 Three.js 中用于从 2D 路径形状(…...

Silky-CTF: 0x02靶场
Silky-CTF: 0x02 来自 <Silky-CTF: 0x02 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128,靶场IP192.168.23.131 3,对靶机进…...

Kafka 的优势是什么?
Kafka 作为分布式流处理平台的核心组件,其设计哲学围绕高吞吐、低延迟、高可扩展性展开,在实时数据管道和大数据生态中具有不可替代的地位。 一、超高吞吐量与低延迟 1. 磁盘顺序 I/O 优化 突破磁盘瓶颈:Kafka 将消息持久化到磁盘ÿ…...

基于FPGA + JESD204B协议+高速ADC数据采集系统设计
摘 要: 针对激光扫描共聚焦显微镜的大视场、高分辨率需求,为在振镜扫描的时间内获取更多数据量,设计一种基 于 FPGA 的高速数据采集系统。该系统采用 Xilinx 的 A7 系列 FPGA 作为主控芯片,同时选用 TI 公司提供的 LM…...
微服务中引入公共拦截器
本文使用的微服务版本为springcloudAlbaba :2021.0.4.0 微服务工程,一般公共的东西都放入一个工程,别的微服务都会引入这个工程,比如common-service,那么就可以在这个工程编写一个拦截器:,比如: public cla…...

Ubuntu20.04 LTS 升级Ubuntu22.04LTS 依赖错误 系统崩溃重装 Ubuntu22.04 LTS
服务器系统为PowerEdge R740 BIOS Version 2.10.2 DELL EMC 1、关机 开机时连续按键盘F2 2、System Setup选择第一个 System BIOS 3、System BIOS Setting 选择 Boot Setting 4、System BIOS Setting-Boot Setting 选择 BIOS Boot Settings 5、重启 开启时连续按键盘F11 …...
C++11:unique_ptr的基本用法、使用场景和最佳使用指南
文章目录 1. 简介2. 基本语法和用法2.1. 创建unique_ptr2.2. 访问指向的对象2.3. 所有权管理 3. 自定义删除器4. 数组支持5. 常见使用场景5.1. RAII资源管理5.2. 工厂模式5.3. 容器中存储多态对象5.4. Pimpl(指针到实现)习惯用法 6. 与其他智能指针的比较…...

测量3D翼片的距离与角度
1,目的。 测量3D翼片的距离与角度。说明: 标注A 红色框选的区域即为翼片,本示例的3D 对象共有3个翼片待测。L1与L2的距离、L1与L2的角度即为所求的翼片距离与角度。 2,原理。 使用线结构光模型(标定模式࿰…...

零基础学习计算机网络编程----socket实现UDP协议
本章将会详细的介绍如何使用 socket 实现 UDP 协议的传送数据。有了前面基础知识的铺垫。对于本章的理解将会变得简单。将会从基础的 Serve 的初始化,进阶到 Client 的初始化,以及 run。最后实现一个简陋的小型的网络聊天室。 目录 1.UdpSever.h 1.1 构造…...

谷歌地图2022高清卫星地图手机版v10.38.2 安卓版 - 前端工具导航
谷歌地图2022高清卫星地图手机版是由谷歌公司推出的一款非常好用的手机地图服务软件,用户能够通过精准的导航和定位来查看地图,周边的商店等生活服务都会在地图上显示,用起来超级方便。 谷歌卫星高清地图 下载链接:夸克网盘分享 …...

RAG的ETL Pipeline源码解读
原文链接:SpringAI(GA):RAG下的ETL源码解读 教程说明 说明:本教程将采用2025年5月20日正式的GA版,给出如下内容 核心功能模块的快速上手教程核心功能模块的源码级解读Spring ai alibaba增强的快速上手教程 源码级解读 版本&a…...

杭州白塔岭画室怎么样?和燕壹画室哪个好?
杭州作为全国美术艺考集训的核心区域,汇聚了众多实力强劲的画室,其中白塔岭画室和燕壹画室备受美术生关注。对于怀揣艺术梦想的考生而言,选择一所契合自身需求的画室,对未来的艺术之路影响深远。接下来,我们将从多个维…...
Linux文件系统:从VFS到Ext4的奇幻之旅
Linux文件系统:从VFS到Ext4的奇幻之旅 从虚拟文件到物理磁盘的魔法桥梁 引言:数据宇宙的"时空管理者" 当你在Linux终端输入ls -l时,一场跨越多个抽象层的精密协作悄然展开。文件系统作为操作系统中最复杂且最精妙的子系统之一&…...
5月底 端午节
感觉五月写的很少啊,尤其是这一周,真的事情特别多可能。但是实际上我晚上回宿舍之后大概九点十点这块,最后睡觉一般在十一点半到十二点。这一段时间我基本上都是浪费了。要么在打游戏要么在刷视频。但是最基本的生活保障和学习都没有做好。。…...
为何选择Spring框架学习设计模式与编码技巧?
📌 结论先行 推荐项目:Spring Framework 推荐理由:设计模式覆盖全面 编码技巧教科书级实现 Java 生态基石地位 🏆 三维度对比分析 维度SpringMyBatisXXL-JOB设计模式⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐代码抽象⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐生态价…...
软件评测师 综合测试 真题笔记
计算机组成原理 用作科学计算为主的计算机,其对主机的运算速度要求很高,应该重点考虑 CPU的主频和字长,以及内存容量; 用作大型数据库处理为主的计算机,其对主机的内存容量、存取速度和外存储器的读写速度要求较高; 对…...

晶台光耦在手机PD快充上的应用
光耦(光电隔离器)作为关键电子元件,在手机PD快充中扮演信号隔离与传输的“安全卫士”。其通过光信号实现电气隔离,保护手机电路免受高电压损害,同时支持实时信号反馈,优化充电效率。 晶台品牌推出KL817、KL…...
JS对数据类型的检测
typeof对基本数据类型有用,但是对引用数据类型不行 console.log(typeof 2)//number console.log(typeof [])//object 失效 instanceof只对引用数据类型有用 console.log([] instanceof Array) //true console.log(2 instanceof String) //false constructor基本…...
llama.cpp:纯 C/C++ 实现的大语言模型推理引擎详解一
🚀 llama.cpp:纯 C/C 实现的大语言模型推理引擎详解 一、什么是 llama.cpp? llama.cpp 是一个由 Georgi Gerganov 开源的项目,旨在使用纯 C/C 在 CPU 上运行 Meta 的 LLaMA 系列大语言模型。 它通过量化、优化注意力机制和内存…...

【亲测有效 | Cursor Pro每月500次快速请求扩5倍】(Windows版)Cursor中集成interactive-feedback-mcp
前言:使用这个interactive-feedback-mcp组件可以根据用户反馈来决定是否结束这一次的请求。如果本次请求并没有解决我们的问题,那我们便可以选择继续这次请求流程,直到问题解决。这样的话,就可以避免为了修复bug而白白多出的请求。…...
BaseTypeHandler用法-笔记
1.BaseTypeHandler简介 org.apache.ibatis.type.BaseTypeHandler 是 MyBatis 提供的一个抽象类,通过继承该类并实现关键方法,可用于实现 Java 类型 与 JDBC 类型 之间的双向转换。当数据库字段类型与 Java 对象属性类型不一致时(如ÿ…...