数据类型

js常用数据类型分为基本类型和引用类型

  • 基本类型:null、undefined、数值型、字符串型、布尔型
  • 引用类型:数组、对象

内存空间

var a = [1, 2, 3];
var b = a;
b[2] = 4;
a; // ??

我们都知道结果是[1, 2, 4],因为b和a指向了同一个引用对象所以都可以改变该对象的值,我们用内存空间来深入理解一下。

我们知道在内存中存在两块区域,一个是栈stack,一个是堆heap。 通常我们的基本数据类型存储在栈中,而我们的引用数据类型存于堆中。栈中会有一个指针指向存在于堆中的数据以便于引用。

var arr = [1, 2, 3];

内存图应该是这样:

arr是一个基本类型的变量,该变量内部存储着数组的地址/指针,通过该地址可以找到存在于heap中的Array对象。通常我们说arr是一个引用类型我觉得是不严谨的,应该说:变量arr指向一个引用类型。

这时候会出现一个问题:允许两个指针指向同一个堆数据,这意味着通过其中一个指针篡改了数值那么会影响另一个指针。

var a = [1, 2, 3];
var b = a;

以上变量在内存中的图是这样的:

解决该问题的方法就是重新在heap中创建一个与a指向的引用对象一模一样的对象,然后让b指向它,
像这样:
这样一个b改变了就不会影响a了。

说个题外话:了解这一机制对理解prototype是有很大好处的

function Person(name) {
this.name = name;
}
Person.prototype = {
sayHi() {
console.log("hi, " + this.name);
}
}; var p1 = new Person('lan');
p1.sayHi(); // 'hi, lan'

内存图如下,可以自己理解一下,找一找哪些存在于stack哪些存在于heap:

接上述,直接将a赋值为b这样为浅拷贝,而上上图中则为深拷贝。

js实现深拷贝思路:

  • 先判断所赋值的类型,如果为基本类型则直接拷贝,若为对象类型则在heap中重新生成一个对象,再递归的将值赋值过去。
function deepCopy(obj) {
var result = ''; // 为基本类型
if(obj == null || obj == undefined || typeof obj != 'object')
return obj; // 为引用类型,判断为数组还是为对象
if(obj instanceof Array)
result = [];
else
result = {}; for(var key in obj) {
var current = obj[key];
if(current == null || current == undefined || typeof current != 'object')
result[key] = current;
else
// 不直接调用deepCopy而用arguments.callee
// 以避免函数被赋值给其他变量而出现错误
result[key] = arguments.callee(current);
} return result;
} var a = {
name: 'lan',
age: 20,
birth: [1,2,3,4],
like: {
food: 'fruit',
color: ['pink', 'blue']
}
}; var b = deepCopy(a);
b.birth[2] = 5;
a.birth; // [1, 2, 3, 4]

以上为自己对于指针的一点思考,欢迎指正与扩展。

由js深拷贝引起的对内存空间的一些思考的更多相关文章

  1. js基础梳理-内存空间

    我估计有很多像我这样非计算机专业的人进入到前端之后,总是在写业务代码,思考什么什么效果如何实现,导致很多基础概念型的东西都理解得并不太清楚.经常一碰到群里讨论的些笔试题什么的,总觉得自己像是一个假前端 ...

  2. js中的栈、堆、队列、内存空间

    栈(stack) .堆(heap). 队列(queue)是js的三种数据结构. 栈(stack) 栈的特点是"LIFO,即后进先出(Last in, first out)".数据存 ...

  3. JS 从内存空间谈到垃圾回收机制

     壹 ❀ 引 从事计算机相关技术工作的同学,对于内存空间相关概念多少有所耳闻,毕竟像我这种非计算机科班出身的人,对于栈堆,垃圾回收都能简单说道几句:当我明白JS 基本类型与引用类型数据存储方式不同,才 ...

  4. js内存空间的那点事

    由于js具有自动垃圾回收机制,导致接触js后一直没去关注js的内存分配及变量回收等原理,只是懵懂的了解用变量标记法(null)可以手动的去清除或是回收:是时候弥补这个大坑了... 垃圾回收两种方法 一 ...

  5. JS进阶之---基本数据类型,引用类型,内存空间

    一.内存空间: 为了便于理解,我们暂且先将Js的内存分为栈内存和堆内存. JavaScript具有垃圾自动回收机制,内存的分配与回收都完全实现了自动管理.所以我们在开发时一般会忽视内存空间的问题.但是 ...

  6. JS进阶系列之内存空间

    也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写 ...

  7. 11.1 js中级,数据类型、数据储存方式、作用域内存空间的区别以及例识别。

    一. 基本数据类型和引用数据类型的区别. 1.基本数据类型:基本数据类型就是简单的操作值. 2.引用数据类型:就是把引用的地址赋给变量. 堆内存: 就是存放代码块的,存放形式有两种 1)对象以键值对的 ...

  8. js内存空间详细图解-笔记

    原文参考http://mp.weixin.qq.com/s/NGqdjhoU3MR9LD0yH6tKIw 栈-先进后出堆-类比成书于书架(形象),只要知道Key就可以找到value 基础数据类型(Un ...

  9. JS内存空间详细图解

    JS内存空间详细图解 变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机 ...

随机推荐

  1. POJ 1222 EXTENDED LIGHTS OUT [高斯消元XOR]

    题意: $5*6$网格里有一些灯告诉你一开始开关状态,按一盏灯会改变它及其上下左右的状态,问最后全熄灭需要按那些灯,保证有解 经典问题 一盏灯最多会被按一次,并且有很明显的异或性质 一个灯作为一个方程 ...

  2. C# 简单内存补丁

    写在开头:看了一些视频教程,感觉OD为什么别人学个破解那么容易,我就那么难了呢,可能是没有那么多时间吧. 解释:个人见解:所谓内存补丁,即:通过修改运行程序的内容,来达到某种目的的操作.修改使用Ope ...

  3. 一个巨low的“2048”

    代码就是这样,做的不是4*4而是一个2*2 #include<stdio.h>#include<stdlib.h>#include<time.h>int main( ...

  4. [实例]JAVA生成字母+随机数字并生成文件

    package com.ishow.control.code; import java.io.*; import java.text.SimpleDateFormat; import java.uti ...

  5. XGoServer 一个基础性、模块完整且安全可靠的服务端框架

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  6. typedef介绍

    1.typedef是什么? typedef是C中的类似于extern/static的一个关键字,用于为一种类型引入一个新的名字.并不会分配内存. 2.typedef常见用法? 1) typedef i ...

  7. CSS小技巧使用

    1.清除浮动 浮动给我们的代码带来的麻烦,想必不需要多说,我们会用很多方式来避免这种麻烦,其中我觉得最方便也是兼容性最好的一种是....// 清除浮动 .clearfix{ zoom: 1; } .c ...

  8. 织梦去除tag标签url中的问号

    找到文件 include\taglib\tag.lib.php  大概87行 把 $row['link'] = $cfg_cmsurl."/tags.php?/".urlencod ...

  9. 提高SQL查询效率

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  10. JDK1.7源码分析01-Collection

    同步发布:http://www.yuanrengu.com/index.php/20180221.html Java的集合类主要由两个接口派生而出:Collection和Map.Collection是 ...