JavaScript基础心法 数据类型


Posted in Javascript onMarch 05, 2018

由于自己是野生程序员,在刚开始学习程序设计的时候没有在意内存这些基础知识,导致后来在提到“什么什么是存在栈中的,栈中只是存了一个引用”这样的话时总是一脸懵逼。。

后来渐渐的了解了一些内存的知识,这部分还是非常有必要了解的。

基本数据结构

栈,只允许在一段进行插入或者删除操作的线性表,是一种先进后出的数据结构。

堆是基于散列算法的数据结构。

队列

队列是一种先进先出(FIFO)的数据结构。

JavaScript中数据类型的存储

JavaScript中将数据类型分为基本数据类型和引用数据类型,它们其中有一个区别就是存储的位置不同。

基本数据类型

我们都知道JavaScript中的基本数据类型有:

  • String
  • Number
  • Boolean
  • Undefined
  • Null
  • Symbol(暂时不管)

基本数据类型都是一些简单的数据段,它们是存储在栈内存中。

引用数据类型

JavaScript中的引用数据类型有:

  • Array
  • Object

引用数据类型是保存在堆内存中的,然后再栈内存中保存一个对堆内存中实际对象的引用。所以,JavaScript中对引用数据类型的操作都是操作对象的引用而不是实际的对象。

可以理解为,栈内存中保存了一个地址,这个地址和堆内存中的实际值是相关的。

图解

现在,我们声明几个变量试试:

var name="axuebin";
var age=25;
var job;
var arr=[1,2,3];
var obj={age:25};

可以通过下图来表示数据类型在内存中的存储情况:

JavaScript基础心法 数据类型

此时name,age,job三种基本数据类型是直接存在栈内存中的,而arr,obj在栈内存中只是存了一个地址来表示对堆内存中的引用。

复制

基本数据类型

对于基本数据类型,如果进行复制,系统会自动为新的变量在栈内存中分配一个新值,很容易理解。

引用数据类型

如果对于数组、对象这样的引用数据类型而言,复制的时候就会有所区别了:

系统也会自动为新的变量在栈内存中分配一个值,但这个值仅仅是一个地址。也就是说,复制出来的变量和原有的变量具有相同的地址值,指向堆内存中的同一个对象。

JavaScript基础心法 数据类型

如果所示,执行了var objCopy=obj之后,obj和objCopy具有相同的地址值,执行堆内存中的同一个实际对象。

这有什么不同呢?

当我修改obj或objCopy时,都会引起另一个变量的改变。

为什么?

为什么基础数据类型存在栈中,而引用数据类型存在堆中呢?

  1. 堆比栈大,栈比对速度快。
  2. 基础数据类型比较稳定,而且相对来说占用的内存小。
  3. 引用数据类型大小是动态的,而且是无限的。
  4. 堆内存是无序存储,可以根据引用直接获取。

参考文章

理解js内存分配

原始值和引用值

在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值。
原始值指的就是代表原始数据类型(基本数据类型)的值,即Undefined,Null,Number,String,Boolean类型所表示的值。
引用值指的就是复合数据类型的值,即Object,Function,Array,以及自定义对象,等等

栈和堆

与原始值与引用值对应存在两种结构的内存即栈和堆
栈是一种后进先出的数据结构,在javascript中可以通过Array来模拟栈的行为

原始值是存储在栈中的简单数据,也就是说,他们的值直接存储在变量访问的位置。

堆是基于散列算法的数据结构,在javascript中,引用值是存放在堆中的。
引用值是存储在堆中的对象,也就是说,存储在变量处的值(即指向对象的变量,存储在栈中)是一个指针,指向存储在堆中的实际对象.

例:var obj = new Object(); obj存储在栈中它指向于new Object()这个对象,而new Object()是存放在堆中的。

那为什么引用值要放在堆中,而原始值要放在栈中,不都是在内存中吗,为什么不放在一起呢?那接下来,让我们来探索问题的答案!

首先,我们来看一下代码:

function Person(id,name,age){
this.id = id;
this.name = name;
this.age = age;
}
var num = 10;
var bol = true;
var str = "abc";
var obj = new Object();
var arr = ['a','b','c'];
var person = new Person(100,"笨蛋的座右铭",25);

然后我们来看一下内存分析图:

JavaScript基础心法 数据类型

变量num,bol,str为基本数据类型,它们的值,直接存放在栈中,obj,person,arr为复合数据类型,他们的引用变量存储在栈中,指向于存储在堆中的实际对象。

由上图可知,我们无法直接操纵堆中的数据,也就是说我们无法直接操纵对象,但我们可以通过栈中对对象的引用来操作对象,就像我们通过遥控机操作电视机一样,区别在于这个电视机本身并没有控制按钮。

现在让我们来回答为什么引用值要放在堆中,而原始值要放在栈中的问题:

记住一句话:能量是守衡的,无非是时间换空间,空间换时间的问题

堆比栈大,栈比堆的运算速度快,对象是一个复杂的结构,并且可以自由扩展,如:数组可以无限扩充,对象可以自由添加属性。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。相对于简单数据类型而言,简单数据类型就比较稳定,并且它只占据很小的内存。不将简单数据类型放在堆是因为通过引用到堆中查找实际对象是要花费时间的,而这个综合成本远大于直接从栈中取得实际值的成本。所以简单数据类型的值直接存放在栈中。

Javascript 相关文章推荐
表单JS弹出填写提示效果代码
Apr 16 Javascript
javascript中的继承实例代码
Apr 27 Javascript
JS验证不重复验证码
Feb 10 Javascript
Angular2 组件间通过@Input @Output通讯示例
Aug 24 Javascript
Node.js学习之TCP/IP数据通讯(实例讲解)
Oct 11 Javascript
使用vue打包时vendor文件过大或者是app.js文件很大的问题
Jun 29 Javascript
Angular中的ng-template及angular 使用ngTemplateOutlet 指令的方法
Aug 08 Javascript
基于JS实现数字动态变化显示效果附源码
Jul 18 Javascript
微信自定义分享链接信息(标题,图片和内容)实现过程详解
Sep 04 Javascript
layui.tree组件的使用以及搜索节点功能的实现
Sep 26 Javascript
Vue实现数据请求拦截
Oct 23 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
Jun 02 Javascript
js获取html页面代码中图片地址的实现代码
Mar 05 #Javascript
vue axios 在页面切换时中断请求方法 ajax
Mar 05 #Javascript
node.js通过axios实现网络请求的方法
Mar 05 #Javascript
axios发送post请求springMVC接收不到参数的解决方法
Mar 05 #Javascript
基于vue 添加axios组件,解决post传参数为null的问题
Mar 05 #Javascript
解决vue处理axios post请求传参的问题
Mar 05 #Javascript
解决vue2中使用axios http请求出现的问题
Mar 05 #Javascript
You might like
main.php
2006/12/09 PHP
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
PHP中Static(静态)关键字功能与用法实例分析
2019/04/05 PHP
网页右键ie不支持event.preventDefault和event.returnValue (需要加window)
2013/02/22 Javascript
获得Javascript对象属性个数的示例代码
2013/11/21 Javascript
基于Bootstrap实现tab标签切换效果
2020/04/15 Javascript
Node.js 实现简单小说爬虫实例
2016/11/18 Javascript
浅析location.href跨窗口调用函数
2016/11/22 Javascript
详解vue-cli快速构建vue应用并实现webpack打包
2017/12/13 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
一次让你了解全部JavaScript的作用域
2019/06/24 Javascript
JS前端面试必备——基本排序算法原理与实现方法详解【插入/选择/归并/冒泡/快速排序】
2020/02/24 Javascript
echarts饼图各个板块之间的空隙如何实现
2020/12/01 Javascript
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
Python urllib、urllib2、httplib抓取网页代码实例
2015/05/09 Python
利用python3随机生成中文字符的实现方法
2017/11/24 Python
python中set()函数简介及实例解析
2018/01/09 Python
Python实现文件信息进行合并实例代码
2018/01/17 Python
Ubuntu16.04/树莓派Python3+opencv配置教程(分享)
2018/04/02 Python
Python考拉兹猜想输出序列代码实践
2019/07/05 Python
Python中使用gflags实例及原理解析
2019/12/13 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
2020/01/21 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
Python加速程序运行的方法
2020/07/29 Python
python 用opencv实现图像修复和图像金字塔
2020/11/27 Python
Python tkinter之ComboBox(下拉框)的使用简介
2021/02/05 Python
英国最大线上综合鞋类商城:Office
2017/12/08 全球购物
英国建筑用品在线:Building Supplies Online(BSO)
2018/04/30 全球购物
知识改变命运演讲稿
2014/05/21 职场文书
外贸采购员岗位职责
2015/04/03 职场文书
小学生心理健康活动总结
2015/05/08 职场文书
初中政治教师教学反思
2016/02/23 职场文书
表扬信范文
2019/04/22 职场文书
《卧薪尝胆》读后感3篇
2019/12/26 职场文书
mysql创建存储过程及函数详解
2021/12/04 MySQL