数据类型

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. 【STL】c++ priority_queue的使用方法

    最开始在项目文档看到priority_queue这个模板时,还以为是自己定义的呢,后来查了一下,原来这是STL中存在的一种优先队列. 1.最简单的使用方法 std::priority_queue< ...

  2. iOS图片轮播

    基于ScrollView的图片播放 ScrollView的方法 NSTime的循环 UIPageControl的运用 委托方法 基于iphone5 未做屏幕的适配 import "ViewC ...

  3. Nginx:413 Request Entity Too Large解决

    最近在做给博客添加上传PDF的功能,但是在测试上传文件的过程中遇到了413 Request Entity Too Large错误.不过这个无错误是很好解决的,这个错误的出现是因为上传的文件大小超过了N ...

  4. [POJ 3581]Sequence

    [POJ 3581]Sequence 标签: 后缀数组 题目链接 题意 给你一串序列\(A_i\),保证对于$ \forall i \in [2,n],都有A_1 >A_i$. 现在需要把这个序 ...

  5. vim学习、各类插件配置与安装

    vim学习.各类插件配置与安装 vim 插件 配置 1. vim学习 vim基础学习:根据网上流行基础文章<简明Vim练级攻略>,进阶书籍<vim实用技巧>.注:进阶书籍可以在 ...

  6. HDU1560 DNA sequence IDA* + 强力剪枝 [kuangbin带你飞]专题二

    题意:给定一些DNA序列,求一个最短序列能够包含所有序列. 思路:记录第i个序列已经被匹配的长度p[i],以及第i序列的原始长度len[i].则有两个剪枝: 剪枝1:直接取最长待匹配长度.1900ms ...

  7. Ansible自动化运维笔记1(安装配置)

    1.Ansible的安装 pip install ansible==1.9.1 ansible1.9.1版本依赖的软件有 Python2.6以上版本 paramiko模块 PyYAML Jinja2 ...

  8. Zookeeper笔记二-各种一致性协议解释

    我们知道Zookeeper的一致性是解决分布式事务的. 那么分布式事务代表的是强一致性. 强一致性解决的代表有以下协议(注意这几个协议跟zookeeper是没任何关系的,这是分布式的理论基础): 1. ...

  9. JVM笔记1-内存溢出分析问题与解决

    假设我们项目中JVM内存溢出了,大项目中上百万行代码,是很难定位的.因此我们需要借用一个Memory Analyzer工具, 官网地址为:http://www.eclipse.org/download ...

  10. window下nginx注册成服务

    1. a.下载windows版nginx (http://nginx.org/download/nginx-1.10.0.zip),并且下载注册服务工具, b.下载地址: http://repo.je ...