「前端每日一问(3)」JS 原始类型和引用类型的区别?

407 阅读2分钟

「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战」。

本题难度:⭐

难度评级为个人主观,最高五星,最低一星。

答:

  • 原始类型存的是值,引用类型存的是地址。
  • 引用类型可以动态添加、修改和删除其属性和方法,原始类型不行。

动态属性

  • 引用类型可以动态添加、修改和删除其属性和方法
// 引用类型
const obj = {
  name: 'lin'
}
obj.name = 'xxx' // 修改
obj.age = 18     // 添加
delete obj.age   // 删除
  • 原始类型不行
// 原始类型
const name = 'lin'
name.age = 18  // 尝试给原始类型添加属性,没有报错,但是不生效

console.log(name.age) // undefined

复制值

// 原始类型
let num1 = 1
let num2 = num1
num2 = 2
console.log(num1)   // num1 打印出来为1, num1 的值不会因 num2 的值的改变而受到影响
// 引用类型
let a = [];
let b = a;
b.push(1);
console.log(a)   // a 打印出来为[1],a 的值因 b 的值的改变而受到影响了

image.png

原始类型存储在栈内存里,num1 和 num2 相互独立,互不干扰。

image.png

引用类型存储在堆内存里,a 和 b 指向了同一地址,改变其中任何一个,另一个都会跟着改变。

传递参数

原始类型传参,形参在函数内改变,不会影响实参。

// 原始类型
function addTen (num) {
  num = num + 10
  return num
}

let count = 20

addTen(count)

console.log(count) // 20

引用类型传参,形参在函数内添加、修改和删除其属性和方法,会影响实参。

// 引用类型
function setName(obj) {
  obj.name = 'lin'
}

let person = {}

setName(person)

console.log(person)  // { name: 'lin' }

当然,如果像下面这么做,直接一个新对象赋值给形参,就不会影响实参,

function setName(obj) {
  obj = { name: 'lin' }
}

let person = {}

setName(person)

console.log(person)  // {}

不管怎么样,传递一个对象到函数里面,如果要对这个函数做一些操作,一定要记得先拷贝一下。

结尾

这是阿林持续更文的第 31 天,输出洞见技术,再会~

上一篇:

「前端每日一问(2)」symbol 是什么? 解决了什么问题?

下一篇: 「前端每日一问(4)」谈谈 JS 中的类型转换机制