跳到主要内容

原始值与引用值

原始值与引用值如何存储?​

  • 原始值: undefined、null、boolean、number、string、symbol, 直接存在栈上, 变量保存其实际值;
  • 引用值: object, 值存在堆上, 栈上只保存指向堆的地址;
  • 操作差异: 原始值操作的是栈上的实际值, 引用值操作的是其引用;

为什么原始值不能添加属性?​

let name = "Nicholas";
name.age = 27;
console.log(name.age); // undefined; 写入的是临时包装对象

const person = {};
person.name = "Nicholas";
console.log(person.name); // "Nicholas"
  • 原因: 原始值没有属性, 读取或写入时会临时包装再销毁, 详见 原始包装类型;
  • 引用值: 属性保存在堆上的对象中, 可以持续存在;

复制值时两者有什么区别?​

  • 原始值: 在栈上创建新空间并复制实际值, 两个变量完全独立;

原始值复制

  • 引用值: 在栈上创建新空间并复制地址, 两个变量指向堆上的同一个对象;
const obj1 = {};
const obj2 = obj1;
obj1.name = "Nicholas";
console.log(obj2.name); // "Nicholas"

引用值复制

函数参数是按值还是按引用传递?​

  • 统一口径: JavaScript 的参数全部按值传递;
  • 原始值参数: 传实际值副本, 函数内修改不影响外部;
  • 对象参数: 传地址副本, 函数内修改对象内容会影响外部; 但在函数内给参数重新赋新对象, 不会改变外部变量;
function setName(obj) {
obj.name = "Nicholas"; // 修改原对象, 外部可见
obj = {}; // 只改变局部副本
obj.name = "Greg";
}
const person = {};
setName(person);
console.log(person.name); // "Nicholas"