(三)nodejs循序渐进-值传递和引用传递,深拷贝和浅拷贝(基础篇)

值传递和引用传递


值类型变量:

存在内存的堆中,比如:a=1
引用类型变量 :

1.指针存在于栈中,2.引用类型的具体内容存在于堆中 ex:let a={b:1} a的指针指向 堆中的地址0xffac0ec

正如我在 第二章 说的,

  • number
  • string
  • boolean

这三种常规类型的是值传递, 而array,对象这种就属于引用传递了。

代码来说话,我们先看看

值传递:

var int1 = 12;
var int2 = int1;
int1 = 10000;
console.log(int2);

var b1 = true;
var b2 = b1;
b2 = false;
console.log(b1);

var str1="hello world";
var str2=str1;
str2="高司机,出bug了";
console.log(str1);

输出结果为

12
true
hello world

引用传递:

let obj1 = {};
let obj2 = null;
obj2 = obj1;
obj1.a = "a";
obj2.b = "b";
//引用类型 指向 同一个堆的区域
console.log(obj1);
console.log(obj2);

输出结果为

{ a: 'a', b: 'b' }
{ a: 'a', b: 'b' }

在逻辑运算中使用值传递和引用传递

let v1 = new String("hello world");
let v2 = v1;
v1 = "出BUG了"; 

console.log(v1); 
console.log(v2); 

不知道是不是和你想的一样,结果是下main的 

出BUG了
[String: 'hello world']

我们来分析下://第二行v2引用的是V1,当运行到第三行的时候v1 变为基本类型时,相当于在内存中有一个新的堆空间,v1的内存地址指向自己本身堆的地址,所以v1输出“出BUG了”,那么v2呢,v2依然是对象类型 而v2不受v1的改变而改变,依然是通过栈的指针 指向new String('"helloworld')对象的内存地址。

在函数中使用值传递和引用传递

function addOne(num) {
num += 1;
return num;
}

var count = 10;
var result = addOne(count);
console.log(count);
console.log(result);

/调用addOne(num) 参数num相当于 在方法中拷贝了一个新的num值在堆中,方法内的改变,不会影响到外部变量

10
11

引用传递

let objj = { a: 1 };
function objAdd(obj) {
obj.b = 1;
}
objAdd(objj);
//引用传递,相当于传递的是obj的指针,会影响外部变量 堆中的值
console.log(objj);
{ a: 1, b: 1 }

在引用和值传递中交叉使用

var person = new Object();
var obj = person; // 赋值
obj.name = "ABC";
obj = new Object(); // 指向 新的对象
obj.name = "BCD";
console.log(person.name); // 指向老的对象 不受影响
console.log(obj.name); // 指向新的对象

console

ABC
BCD

 

深拷贝和浅拷贝

之前在第二章节我答应过要专门说深拷贝和浅拷贝,这个原理实际上和C++是类似的。

实际上浅拷贝你可以理解为简单的引用拷贝。

所谓深拷贝就是自己新建一个数组或者对象,把源数组或者对象中的基础类型变量值一个个手动拷过去,而不是只把源数组或者对象的引用拿过来。所以这就涉及到了一个递归的调用什么的。

下面是我实现的一个深拷贝函数,大家可以写一个自己的然后加入到自己的 nodejs 知识库中。

function cloneObject(src) {
    var dest = {};
    for(var key in src) {
        if(typeof src === "object") dest[key] = cloneObject(src[key]);
        else dest[key] = src[key];
    }

    return dest;
}
已标记关键词 清除标记
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值