You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查看JavaScript/TypeScript变量的内存地址?关于传值与传引用的疑问

在现代JavaScript/TypeScript中获取变量内存地址 & 理解传值/传引用

嘿,这个问题问到点子上了——内存地址确实是搞清楚JS参数传递逻辑的核心钥匙,我来给你掰扯清楚:

1. 标准JS/TS里能直接获取内存地址吗?

答案是不行。

JavaScript(包括TypeScript,因为它只是JS的超集)是一门高层抽象语言,引擎(比如V8)帮我们全权管理内存分配、回收这些底层细节,并没有暴露直接读取变量内存地址的API。这么设计的原因很简单:

  • 安全:暴露内存地址可能带来内存泄露、非法访问等风险;
  • 抽象性:JS的核心设计就是让开发者不用关心底层内存,专注于业务逻辑。

2. 不用内存地址,怎么理解传值/传引用?

很多人会混淆JS的传递机制,其实准确来说:JS里只有「传值调用」,但这个「值」的类型分两种:

  • 对于原始类型(string、number、boolean、null、undefined、symbol、bigint):传递的是值的副本。也就是说,函数拿到的是和外部变量完全独立的一个值,修改它不会影响外部的原始变量。
    举个例子:

    let age = 25;
    function updateAge(newAge) {
      newAge = 30;
    }
    updateAge(age);
    console.log(age); // 还是25,因为函数里改的是副本
    
  • 对于引用类型(对象、数组、函数等):传递的是「指向对象的引用的副本」。你可以把这个引用想象成一个“内存地址的替身”——函数拿到的是这个替身的副本,所以它和外部变量的引用指向同一个内存里的对象。这时候修改对象的属性会影响外部,但如果给参数重新赋值一个新对象,就和外部没关系了(因为副本指向了新的对象地址)。
    举个例子:

    let user = { name: "张三" };
    function updateUser(u) {
      u.name = "李四"; // 修改的是同一个对象的属性,外部会受影响
      u = { name: "王五" }; // 给副本引用赋值新对象,和外部无关
    }
    updateUser(user);
    console.log(user.name); // 输出「李四」
    

3. 有没有间接方式模拟“内存地址”?

如果只是为了区分不同对象是不是同一个(即是否指向同一块内存),可以用WeakMap给每个对象绑定一个唯一标识,当作“伪内存地址”:

const objIdentifier = new WeakMap();
let idCounter = 0;

function getUniqueId(obj) {
  if (objIdentifier.has(obj)) {
    return objIdentifier.get(obj);
  }
  const newId = ++idCounter;
  objIdentifier.set(obj, newId);
  return newId;
}

const objA = {};
const objB = objA;
const objC = {};

console.log(getUniqueId(objA)); // 1
console.log(getUniqueId(objB)); // 1(和objA是同一个对象)
console.log(getUniqueId(objC)); // 2(新对象)

注意:这不是真正的内存地址,只是对象的唯一标识,而且WeakMap不会阻止垃圾回收,不会造成内存泄露,是比较安全的方式。

内容的提问来源于stack exchange,提问作者SAURABH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:46:26