ECMAScript原始值与引用值深度解析
本文深入解析ECMAScript中的原始值与引用值概念。详细阐述Undefined、Null等六种原始值的特性,以及引用值在内存中的存储与动态属性操作。对比两者在变量复制时的行为差异,并介绍typeof与instanceof在类型判断中的应用与局限。
前言
这是JavaScript中非常基础的概念,但许多开发者往往浅尝辄止,导致在面试中难以应对相关提问。本文结合过往笔记,对原始值(primitive value)和引用值(reference value)的核心知识进行梳理与回顾,帮助大家巩固基础。
根据ECMAScript规范,变量只能存储两种类型的数据:原始值或引用值。原始值代表最基础的数据形式,而引用值则是由多个数据组成的对象集合。
ECMAScript定义了六种原始值类型,分别为:Undefined、Null、Boolean、Number、String以及Symbol。在处理原始值时,我们实际上是在直接操作存储在变量中的具体数值。
引用值则是存储在内存中的对象。由于JavaScript语言机制限制,开发者无法直接访问或操作内存地址,因此操作对象实质上是操作指向该对象的引用(指针),而非对象本身。
动态属性
动态属性指的是在创建引用值对象后,可以灵活地为其添加、修改或删除属性和方法。具体操作示例如下:
let obj = new Object();
obj.name = "Sam";
console.log(obj.name); // "Sam"
解析:首先实例化一个引用值对象并赋值给变量obj,随后为obj赋予name属性,其值为“Sam”。只要该属性未被后续代码修改或删除,即可直接通过变量访问或打印该属性值。
原始值类型不具备动态属性的特性。虽然尝试给原始值添加属性时不会抛出错误,但该操作实际上无效。示例如下:
let me = "Sam";
me.sex = "男";
console.log(me.sex); // undefined
此处采用字面量方式初始化变量,因此即便尝试给me添加sex属性,也无法成功访问该属性,结果仍为undefined。 若使用new关键字来初始化原始值包装对象,JavaScript会创建一个对应的Object实例。示例如下:
let me = new String("Sam");
me.sex = "男";
console.log(me.sex); // "男"
值的复制
原始值与引用值在变量赋值(复制)时的行为存在显著差异。原始值的复制会将实际数据拷贝至新变量,而引用值的复制仅拷贝指向内存中对象的指针。具体示例如下:
let name = "Sam";
let myName = name;
console.log(myName); // "Sam"
当将name的值赋给myName时,字符串“Sam”会被完整复制一份到myName中。此时myName与name相互独立,互不影响,可以视为myName是name的一个独立副本。
引用值的复制实际上是指针的传递,两个变量指向堆内存中的同一个对象。因此,对复制后的变量进行属性修改,实际上是在操作原对象,两个变量共享同一数据。示例如下:
let me = new Object();
let you = me;
me.name = "Sam";
console.log(you.name); // "Sam"
判断值类型
开发者常使用typeof运算符来检测变量类型,这对原始值类型判断非常有效。然而,对于引用值的判断,typeof往往返回“object”,且null也会被识别为object,导致区分困难。
为了更精确地判断引用值的具体类型,可以使用instanceof操作符。其基本语法如下:
result = variable instanceof constructor
instanceof运算符返回一个布尔值,用于判断对象是否为某个构造函数的实例。具体示例如下:
console.log(person instanceof Object);
// 变量 person 是 Object 吗?
console.log(colors instanceof Array);
// 变量 colors 是 Array 吗?
console.log(pattern instanceof RegExp);
// 变量 pattern 是 RegExp 吗?
需要注意的是,如果使用instanceof检测原始值,结果始终为false,因为原始值并非对象实例。
总结
至此,关于ECMAScript中原始值与引用值的解析已完成。如需了解更多相关内容,建议查阅本站历史文章或继续阅读后续系列教程,感谢大家的支持。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38








