基本类型按值操作,赋值复制值本身,修改不影响原变量;引用类型按引用操作,赋值复制地址,修改相互影响。可通过赋值影响、属性添加、typeof/instanceof、内存位置四方面判断。

直接看变量值的“本质”和“行为”,而不是只看写法。字面量不等于基本类型,对象也不一定非得用 new 创建——关键在它底层是按值操作还是按引用操作。
看赋值后是否相互影响
这是最直观的判断方式:
- 基本类型字面量(如
42、"hi"、true)赋值时复制的是值本身,修改副本不影响原变量 - 引用类型对象(如
{}、[]、function(){})赋值时复制的是内存地址,两个变量指向同一块堆内存,改一个,另一个跟着变
看能否动态添加属性
基本类型无法真正拥有属性,即使临时写上也读不到:
let s = "abc"; s.foo = 123; console.log(s.foo); // undefinedlet o = {}; o.foo = 123; console.log(o.foo); // 123
这是因为字符串、数字、布尔值这些基本类型是不可变的,引擎不会为它们持久维护属性空间。
看 typeof 和 instanceof 的返回结果
基础类型有明确的 typeof 值:
-
typeof 42→"number" -
typeof "x"→"string" -
typeof null→"object"(这是历史 bug,但已成规范) -
typeof []或typeof {}→ 都是"object",这时需进一步用Array.isArray()或o.constructor === Object辅助判断
看内存存放位置与可变性
基本类型值存在栈中,固定大小,内容不可修改;引用类型实际数据存在堆中,变量里存的是地址,因此支持增删属性、修改元素等可变操作:
let a = [1,2]; let b = a; b.push(3); console.log(a); // [1,2,3]let x = "ab"; let y = x; y += "c"; console.log(x); // "ab"(没变)
注意:像 String、Number、Boolean 构造函数(带 new)创建的是包装对象,属于引用类型,但日常应避免使用,容易引发混淆。











