(三)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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444550.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(四)nodejs循序渐进-函数,类和对象(基础篇)

上一篇文章讲到了基本数据类型和运算符,相信大家都能做简单的运算,本篇文章将讲述函数,类,对象。 函数 在nodejs中,一个函数可以作为另一个函数的参数。我们可以先定义一个函数,然后传递,也可…

leetcode38. 外观数列

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 被读作 "one 1" ("一个一") , 即 11。 11 被读作 "two …

(五)nodejs循序渐进-回调函数和异常处理(基础篇)

上篇文章我们讲完了类和对象,接下来我们将要说回调函数. 我在第一篇说到nodejs的一个优势是异步IO,实际上异步IO直接体现就是使用回调函数,当然不是用了回调函数,他就一定是异步IO的,因为inodejs是一个单线程函数&…

(六)nodejs循序渐进-数据流和文件操作(基础篇)

Buffer JS 语言自身只有字符串数据类型,没有二进制数据类型,因此 NodeJS 提供了一个与 String 对等的全局构造函数 Buffer 来提供对二进制数据的操作。除了可以读取文件得到 Buffer 的实例外,还能够直接构造,Buffer 与字符串类似…

leetcode171. Excel表列序号

给定一个Excel表格中的列名称,返回其相应的列序号。 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ... 示例 1: 输入: "A" 输出: 1 示例 2: 输入: "AB" 输出: 28 …

(七)nodejs循序渐进-模块系统(进阶篇)

模块系统 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或…

(八)nodejs循序渐进-事件驱动(进阶篇)

事件驱动程序 Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。 当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。 这个模型…

leetcode304. 二维区域和检索 - 矩阵不可变

给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。 上图子矩阵左上角 (row1, col1) (2, 1) ,右下角(row2, col2) (4, 3),该子矩形内元素的总和为 8。 示例…

(九)nodejs循序渐进-Express框架(进阶篇)

Express 框架 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。 使用 Express 可以快速地搭建一个完整功能的网站。 Express 框架核心特性: 可以设置中间件来响应 HTTP 请求。 定…

leetcode326. 3的幂 如此6的操作你想到了吗

给定一个整数,写一个函数来判断它是否是 3 的幂次方。 示例 1: 输入: 27 输出: true 示例 2: 输入: 0 输出: false 示例 3: 输入: 9 输出: true 示例 4: 输入: 45 输出: false 进阶: 你能不使用循环或者递归来完成本题吗? 注意最后一句…

(十)nodejs循序渐进-高性能游戏服务器框架pomelo之介绍和安装篇

目录 Pomelo 安装Pomelo 创建demoserver项目 pomelo命令 项目结构说明 pomelo框架 架构 服务器实现 客户端请求与响应、广播的抽象介绍 Pomelo pomelo是一个快速、可扩展、Node.js分布式游戏服务器框架,对游戏服务器开发感兴趣的同学可以关注关注。 之前…

leetcode344. 反转字符串 史上最简单力扣题

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。…

(十一)nodejs循序渐进-高性能游戏服务器框架pomelo之启动流程和组件

游戏启动过程 启动入口 在使用pomelo进行游戏开发时,工程目录下的app.js是整个游戏服务器的启动运行入口。app.js中创建项目,进行默认配置并启动服务器的代码如下: var pomelo require(pomelo); var app pomelo.createApp(); app.set(na…

(十二)nodejs循序渐进-高性能游戏服务器框架pomelo之创建一个游戏聊天服务器

上个章节我们简单介绍了下pomelo的安装和目录结构,有读者可能觉得有点吃不消,为什么不再深入讲一讲目录结构和里边的库,这里我就不费口舌了,大家可以去官网参考文档说明,本文只告诉大家如何利用这个框架来开发自己的东…

看这玩意复习你还会挂科?《软件工程篇》

软件工程:是指导软件开发和维护的一门工程学科 三要素方法/工具/开发过程 价值:促进项目成功 现代产品开发三原则:功用性、可行性、称许性 软件过程是软件工程的核心组成部分。 迭代 :反复求精 增量:逐块建造 需…

C++:02---命名空间

一、概念: ①类似于仓库,空间内存储代码,需要用到时调用②也为防止名字冲突提供了更加可控的机制二、命名空间的定义 定义的基本格式如下:namespace 命名空间名 { //一系列声明与定义 };三、命名空间的注意事项 命名空间定义时最后的分号可有可无只要出现在全局作用域中的…

看这玩意复习你还会挂科?《软件工程2篇》

第一章: 软件工程定义: 1968年10月,Fritz Bauer 首次提出了“软件工程”的概念,并将“软件工程”定义为:为了经济地获得能够在实际机器上有效运行的可靠软件,而建立并使用的一系列工程化原则。 1993年IE…

C++:05---命名空间

一、概念: ①类似于仓库,空间内存储代码,需要用到时调用②也为防止名字冲突提供了更加可控的机制二、命名空间的定义 定义的基本格式如下:namespace 命名空间名 { //一系列声明与定义 };三、命名空间的注意事项 命名空间定义时最后的分号可有可无只要出现在全局作用域中的…

C++:04---内联函数

1.概念: 内联类似于宏定义,当程序执行到内联函数时,相当于复制了一份函数代码。牺牲代码空间,赢得了时间 内联说明只是向编译器发出一个请求,编译器可以选择忽略这个请求 2.关键字:inline 声明时写了inline,定义时可省略。建议声明和定义都加上inlineinline int add(int…

leetcode86. 分隔链表

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例: 输入: head 1->4->3->2->5->2, x 3 输出: 1->2->2->4->3->5…