谈谈我对JavaScript值传递和引用传递的理解

一、问题起源

var a = 0;
var x = a;
a = 1;
console.log(a); //1
console.log(x); //0

第一段代码中,a与x互不影响;

var b = {n:0};
var y = b;
b = {n:0};
console.log(b); //{n:0}
console.log(y); //{n:0}, 

第二段代码,只更改了b,y却也跟着变了。

为什么呢?因为在x = a的赋值是值传递,而在y = b的赋值是引用传递

二、堆栈结构、原始值和引用值

在JavaScript中,每声明一个变量,CPU便会在中申请一个区域,用以存放变量的值。那么在赋值给变量时会出现以下两种情况:

  1. 将简单的数据段赋值给变量时,可将他们直接存储在较小的内存区域 - 栈中;
     此时,存放在变量中的值是数据段本身,即原始值

  2. 对于较复杂的数据段(譬如对象),它们的占据大小无法确定,时而十分庞大,直接存于栈中会占用大量空间。此时,可以将复杂数据段存放在较大区域 - 中,并生成一个指向该数据段的首地址值存于栈中。
     此时,存放在变量中的值是数据段的首地址值,即引用值

堆栈结构
也就是说,在JavaScript中,变量可以存储着两种类型的值,原始值和引用值。

var num = 0; //变量num中存的是原始值,也就是number数据0
var obj = {n:0}; //变量obj中存的是引用值,也就是object数据{n:1}的首地址值

在这里插入图片描述

三、数据类型

了解值传递和引用传递之前,首先要理解JavaScript的数据类型。

ES6 标准定义了 7 种数据类型:

6种原始类型(Primitive type)

  • boolean
  • null
  • undefined
  • number
  • string
  • symbol ( new in ES6, 暂不考虑 )

和对象object

注意:var str = new String(); 中str = {" ", length}是object

四、值传递和引用传递

1. 原始值和值传递

原始值即数据本身,在JavaScript的原始类型数据boolean、undefined、null、number、string均为简单数据段。当将这些数据赋值给变量时,是直接将数据本身存储在变量容器中,这便是值传递
原始值和值传递

var a = true;
var b = undefined;
var c = "ccc"
var x = a, y = b, z = c;
x = 99;
console.log(a); //true
console.log(b); //undefined
console.log(c); //ccc
console.log(x); //99
console.log(y); //undefined
console.log(z); //ccc

在变量abcxyz中,存储的是数据本身。在执行x = a赋值时,直接将a中的原始值复制给了x,所以在对变量x进行操作时,不会影响变量a。

2. 引用值和引用传递

引用值即存储于堆中的对象的首地址值。将对象 {n:0} 赋值给变量x时,会在堆中申请一块空间存储对象数据 {n:0} ,并将其首地址值放在变量x中,这便是引用传递

引用值与引用传递

var x = {n:0};
var y = x;
var z = {n:9};
console.log(x); //{n:0}
y.n = 1;
console.log(x); //{n:1}
console.log(z); //{n:9}

在变量xyz中,存储的是引用值,在y = x赋值时,是将x中存储的引用值复制给y,它们指向同一个对象。所以操作y时,实际上是在操作y所指向的对象。这就导致了,虽然代码中只操作了y,但x也随之改变,而变量z所指向的对象不同,它并没有被影响。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值