搞不懂JS中赋值·浅拷贝·深拷贝的请看这里
前言
百科定义:拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的时候,指向这个内存空间的所有指针需要重新定义,不然会造成野指针错误。
拷贝内容总结
数据类型与堆栈的关系
基本类型与引用类型
- 基本类型:undefined,null,Boolean,String,Number,Symbol
- 引用类型:Object,Array,Date,Function,RegExp等
存储方式
- 基本类型:基本类型值在内存中占据固定大小,保存在
栈内存中(不包含闭包中的变量) - 引用类型:引用类型的值是对象,保存在
堆内存中。而栈内存存储的是对象的变量标识符以及对象在堆内存中的存储地址(引用),引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
注意:
闭包中的变量并不保存在栈内存中,而是保存在堆内存中。这一点比较好想,如果闭包中的变量保存在了栈内存中,随着外层中的函数从调用栈中销毁,变量肯定也会被销毁,但是如果保存在了堆内存中,内存函数仍能访问外层已销毁函数中的变量。看一段对应代码理解下:
function A() {
let a = 'koala'
function B() {
console.log(a)
}
return B
}
基本数据类型复制配图:
结论:在栈内存中的数据发生数据变化的时候,系统会自动为新的变量分配一个新的之值在栈内存中,两个变量相互独立,互不影响的。
引用数据类型复制
看一段代码
let a = {x:'kaola', y:'kaola1'}
let b = a;
b.x = '程序员成长指北';
console.log(a.x); // 程序员成长指北
引用类型的复制,同样为新的变量b分配一个新的值,报错在栈内存中,不同的是这个变量对应的具体值不在栈中,栈中只是一个地址指针。两个变量地址指针相同,指向堆内存中的对象,因此b.x发生改变的时候,a.x也发生了改变。
浅拷贝
浅拷贝定义:
不知道的api我一般比较喜欢看MDN,浅拷贝的概念MDN官方并没有给出明确定义,但是搜到了一个函数Array.prototype.slice,官方说它可以实现原数组的浅拷贝。
对于官方给的结论,我们通过一段代码验证一下,并总结出浅拷贝的定义。
var a = [ 1, 3, 5, { x: 1 } ];
var b = Array.prototype.slice.call(a);
b[0] = 2;
console.log(a); // [ 1, 3, 5, { x: 1 } ];
console.log(b); // [ 2, 3, 5, { x: 1 } ];从输出结果可以看出,浅拷贝后,数组a[0]并不会随着b[0]改变而改变,说明a和b在栈内存中引用地址并不相同。
浅拷贝定义:
通过这个官方的slice浅拷贝函数分析浅拷贝定义:
新的对象复制已有对象中非对象属性的值和对象属性的引用。如果这种说法不理解换一种一个新的对象直接拷贝已存在的对象的对象属性的引用,即浅拷贝。
深拷贝操作
说了赋值操作和浅拷贝操作,大家是不是已经能想到什么是深拷贝了,下面直接说深拷贝的定义。
深拷贝定义
深拷贝会另外拷贝一份一个一模一样的对象,从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
搞不懂JS中赋值·浅拷贝·深拷贝的请看这里的更多相关文章
- python中赋值-浅拷贝-深拷贝之间的关系
赋值: 变量的引用,没有拷贝空间 对象之间赋值本质上 是对象之间的引用传递而已.也就是多个对象指向同一个数据空间. 拷贝的对象分两种类型: . 拷贝可变类型 浅拷贝: 只拷贝第一层数据,不关心里面的第 ...
- 让你彻底搞懂JS中复杂运算符==
让你彻底搞懂JS中复杂运算符== 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一. 在仔细阅读了ECMA ...
- 彻底搞懂 JS 中 this 机制
彻底搞懂 JS 中 this 机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 目录 this 是什么 this 的四种绑定规 ...
- 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
作为一名前端工程师,必须搞懂JS中的prototype.__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞 ...
- 一文搞懂 js 中的各种 for 循环的不同之处
一文搞懂 js 中的各种 for 循环的不同之处 See the Pen for...in vs for...of by xgqfrms (@xgqfrms) on CodePen. for &quo ...
- js引用类型赋值,深拷贝与浅拷贝
JS中引用类型使用等号“=” 赋值,相当于把原来对象的地址拷贝一份给新的对象,这样原来旧的对象与新的对象就指向同一个地址,改变其中一个对象就会影响另外那个对象,也就是所谓的浅拷贝.例如: var ar ...
- 在js中如何区分深拷贝与浅拷贝?
一.自我理解 简单来讲就是:深拷贝层层拷贝,浅拷贝只拷贝第一层. 在深拷贝中,新对象中的更改不会影响原对象,而在浅拷贝中,新对象中的更改,原对象中也会跟着改. 在深拷贝中,原对象与新对象不共享相同的属 ...
- 浅谈js中的浅拷贝和深拷贝
在js中如何把一个对象里的属性和方法复制给另一个对象呢? 下面举一个例子来说明: var person={name:'chen',age:18}; var son={sex:'男'}; functio ...
- 晨叔技术晨报: 你真的搞懂JS中的“值传递”和“引用传递”吗?
晨叔周刊,每周一话题,技术天天涨. 本周的话题是JS的内存问题(加入本周话题,请点击传送门). 图 话题入口 今天的技术晨报来,就来谈谈JS中变量的,值传递和引用传递的问题.现在,对于很多的JSer来 ...
随机推荐
- Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1)
A. Alternating Sum 就是个等比数列,特判公比为 $1$ 的情况即可. #include <bits/stdc++.h> using namespace std; ; ; ...
- 虚拟机中Windows激活「很抱歉,程序无法在非MBR引导分区上进行激活」
虚拟机激活 Windows 出现如下错误提示: 很抱歉,程序无法在非MBR引导分区上进行激活 没错,是小马Oem7F7激活工具. 最后使用 KMS 激活成功,下载链接: 链接:https://pan. ...
- Anaconda3(4)安装pytorch
安装链接 https://pytorch.org/ 0在anaconda3安装python3.6环境 https://blog.csdn.net/u012005313/article/details ...
- 研究下vc++的abort函数
最近在调试几个问题时,发现跟abort函数有关,以前只是简单使用,现在却发现不简单,就多留意了下. 简介 abort中止当前进程并返回错误代码.异常终止一个进程.中止当前进程,返回一个错误代码.错误代 ...
- [RN] React Native 好用的时间线 组件
React Native 好用的时间线 组件 效果如下: 实现方法: 一.组件封装 CustomTimeLine.js "use strict"; import React, {C ...
- js中的new操作符解析
new 操作符做了以下事情: 1.创建一个对象,将对象赋值给this function Person(name, age) { console.log(this) //Person {} } let ...
- Java集合详解4:一文读懂HashMap和HashTable的区别以及常见面试题
<Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...
- Linux搭建Nexus3.X构建maven私服
备注:linux版本: ubuntu 同时已经部署好JDK8环境 一.linux安装nexus 1.创建文件夹并进入该目录 cd /usr/local && mkdir nexus & ...
- [原创] C#编程规范工具介绍
1.目标 代码编写规范.整齐.整洁.可读. 无错误 无警告 2.排版 安装PowerCommands扩展 “工具”-“扩展管理库”,搜索安装. 设置选中Format document on save和 ...
- unity内存管理(转)
转自:https://www.cnblogs.com/zsb517/p/5724908.html Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBun ...