数据类型

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. BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]

    RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...

  2. 用js脚本一键下载网页所有图片

    年前这两天稍微闲一点了,琢磨了一点js脚本,功能是把当前网页页面上的所有图片一次性保存到本地,免得每次都要对图片右键保存. 测试环境:Chrome开发者模式下(启动Chrome,按F12即可) 测试网 ...

  3. 数据分析之pandas教程-----概念篇

    目录 1  pandas基本概念 1.1  pandas数据结构剖析 1.1.1  Series 1.1.2  DataFrame 1.1.3  索引 1.1.4  pandas基本操作 1.1.4. ...

  4. JDBC【介绍JDBC、使用JDBC连接数据库、简单的工具类】

    1.什么是JDBC JDBC全称为:Java Data Base Connectivity,它是可以执行SQL语句的Java API 2.为什么我们要用JDBC 市面上有非常多的数据库,本来我们是需要 ...

  5. C++ 内存分配(new,operator new)面面观 (转)

    本文主要讲述C++ new运算符和operator new, placement new之间的种种关联,new的底层实现,以及operator new的重载和一些在内存池,STL中的应用. 一 new ...

  6. Centos-7 + Docker-1.12 中 devicemapper + direct_lvm 的 Docker 存储配置

    html,body { font-size: 12pt } body { font-family: Helvetica, "Hiragino Sans GB", "微软雅 ...

  7. Nginx配置参数中文说明

    #定义Nginx运行的用户和用户组 user www www;   #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8;   #全局错误日志定义类型,[ debu ...

  8. httping:测量网站延迟

    遇到网络问题的时候,我们一般会先通过 ping 这个工具来了解基本的情况.httping 与 ping 类似,不过它不是发送 ICMP 请求,而是发送 HTTP 请求.利用 httping,我们可以测 ...

  9. OpenCV角点检测goodFeaturesToTrack()源代码分析

    上面一篇博客分析了HARRIS和ShiTomasi角点检测的源代码.而为了提取更准确的角点,OpenCV中提供了goodFeaturesToTrack()这个API函数,来获取更加准确的角点位置.这篇 ...

  10. MySql主键自动生成,表、实体、C#调用方法

    1.表:mysql建表语句 DROP TABLE IF EXISTS `keycode`; CREATE TABLE `keycode` ( `Id` ) NOT NULL AUTO_INCREMEN ...