JS中的原始值、引用值、按值传递


关于JavaScript中的原始值与引用值以及按值传递

对于JS中的变量只存储两种类型的值,原始值和引用值。

原始值

原始值就是最简单的数据,也就是几种基本数据类型的值。原始值存储在栈内存中,通过变量可以直接访问到,是按值访问的。

为什么存储在栈中呢?
因为原始值占据空间大小固定,所以存储在栈内存中,方便快速查找。

对于原始值的复制值
let num1=5
let num2=num1
console.log(++num1)		//6
console.log(num2)		//5

第一行num1变量存储数值5,第二行num2初始化为num1,该变量也同样存储数值5。但是这两个变量中的数值5是完全独立的,两个变量可以独立使用,互不干扰。如下图:

图1-1 num1初始化
图1-2 num2初始化
引用值

引用值是储存在堆内存中的对象,在JS中不允许我们直接去访问该内存位置,所以保存在变量中的值为指针,这个指针指向了堆内存中的对象,我们并没有直接去操作对象,而是通过保存在变量中的指针去间接的操作对象,所以是按引用访问的。
保存在变量中的值为该对象在对堆内存中的位置。这个值大小固定,存储在栈内存中。如图:
请添加图片描述

对于引用值的复制值
let obj1=new Object()
let obj2=obj1
obj1.num=1		//为obj1对象添加num属性属性值为1
consol.log(obj2.num)	//1		通过obj2也可以访问num属性,这是为什么呢?

在第一行中我们为obj1“new”出了一个新的实例对象,在第二行中执行了一个复制值的操作,虽然有值的复制但是并没有在内存中重新开辟新的空间,也就是说这一步复制的值就相当于一个指针,该指针指向内存中的对象(obj1所指向的对象)。这样obj2和obj1通过指针指向同一内存地址,无论哪一个改变了,内存中的对象都会改变。如下图:

图2-1 执行复制值之前
图2-2执行复制值之后
函数传参(按值传递)

JS中所有函数传参都是按值传递的。也就是说传递的参数会被复制到函数内部的参数中,就像两个变量进行复制操作一样

function add(num){
	return ++num
}
let n=10
console.log(add(n))		//11
console.log(n)		//10

我们可以发现对于原始值(基本数据类型)传参(按值传递),函数内部的操作不会影响到外部,这很好理解。正如开头说的,传参相当于执行了复制操作,对于原始值复制值两个变量是完全独立的。

function setPerson(obj){
	obj.name="kobe"
}
const p=new Object()		//创建一个p对象
setPerson(p)
console.log(p.name)		//kobe

对于引用值传参(按值传递),函数内部的操作会影响到外部,很多人认为这就是按引用传递其实是不对的。看下面代码:

function setPerson(obj){
	obj.age=20
    obj=new Object()
    obj.age=22
}
const p =new Object()
setPerson(p)		
console.log(p.age)		//20

如果对于引用值函数传参是按引用传递的话,在函数体内部obj指向了一个新的对象,并且为对象添加age属性,属性值为22 ,外部p也应指向新对象并且age也应该为22,但是结果确是20,足以说明这并不是按引用传递而是按值传递。

在函数体内的过程:

按值传递实参p会将指针复制给实参obj,此时他们共同指向存放在全局作用域堆内存中的对象,所以添加属性age并为其赋值外部实参也会产生相应的变化

图3-1 传递参数

obj在函数内部被重写,他的指针指向了本地对象,而原本的实参p是不受影响的,这个本地对象在函数执行之后会被销毁。

总结

  • 原始值大小固定,保存在栈内存中
  • 引用值是对象,保存在堆内存中
  • 保存引用值的变量实际上保存了指向该对象的指针,并不是保存变量本身
  • 复制原始值(从一个变量到另一个变量)是创建了一个新值,二者是并无关系的
  • 复制引用值(从一个变量到另一个变量)复制了指针,所以二者指向了同一个对象
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值