JS变量

一步一步重温 JavaScript 基础系列。
本章节将会理解JS的变量,包括变量的含义、变量的值、复制变量的值,以及传递参数

1 概念

JavaScipt变量松散类型的本质,决定了变量只是在特定时间内用于保存特定值的一个名字,或者称之为引用。

2 变量的值

分为基本类型变量的值,和引用类型变量的值。其中,基本类型变量的值大小固定,存放于栈内存中,允许直接操作,即基本类型变量是按值访问;而引用数据类型变量的值大小不固定,存放于堆内存中,不可直接访问,其引用地址(即变量)存放于栈内存中,故引用数据类型变量的值是按引用访问。

3 复制变量的值

  • 值为基本数据类型的变量,与复制后形成的变量,相互独立,后续赋值各不相干;

  • 值为引用数据类型的变量,复制时,实际上是复制一个指针(或称之为引用),共同指向堆内存中的同一对象。当其中一个变量操作该对象的属性时,另外一个变量对应的属性也会随之改变,因为他们指向的是同一个对象。

实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 值为基本数据类型的变量
var num1 = 5;
var num2 = num1;
num2 ++;

console.log(num1) // 5
console.log(num2) // 6

// 值为引用数据类型的变量
var obj1 = {
name: 'xugang',
age: 30
}
var obj2 = obj1;
obj2.age = 32

console.log(obj1.age) // 32

图解如下:

复制变量的值图解

4 变量作为参数传递 – JS中所有函数的参数都是按值传递

函数在传递参数时,就是把实参复制给形参,即函数的局部变量。如果实参是引用数据类型,则复制形成的行参和实参相互独立,互不影响;如果是引用数据类型,此时,实参复制的是一份指针,共同指向堆内存中的同一对象,所以此时修改形参的属性或属性值,则会影响对应实参的属性和属性值。

那如何理解函数中参数传递,是按值传递,而不是按引用传递?

  1. 如果为按值传递,则复制的是一个指针,共同指向堆内存中的同一对象,此时形参属性和属性值的改变,会影响外部实参的属性和属性值;
  2. 如果为按引用传递,则意味着传递整个变量,此时如果改变局部变量即形参的引用地址,也会相应改变实参的引用地址,这显然和实际不符。

总结如下:
所谓变量作为参数传递是按值传递,是指将外部变量(实参)的值复制给内部局部变量(实参),也就是在栈内存中复制出一份指针,共同指向堆内存的同一对象。函数内部可以通过改变形参的属性和属性值来改变,外部变量(实参)对应的属性和属性值, 但是不能操作外部变量(实参)本身。图解如下:

1
2
3
4
5
6
7
8
9
10
11
12
function setName(obj) {
obj.name = 'xugang';

// 改变局部变量(形参)的引用地址,指向堆内存中的一个新对象
obj = new Object();
obj.name = 'suifeng';
}

var person = new Object();
setName(person);

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

图解如下:

按值传递图解

原创技术分享,您的支持将鼓励我继续创作