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
Jun 19 Javascript
javascript 通用loading动画效果实例代码
Jan 14 Javascript
jquery中$.post()方法的简单实例
Feb 04 Javascript
EasyUI中实现form表单提交的示例分享
Mar 01 Javascript
浅谈JavaScript中的作用域和闭包问题
Jul 07 Javascript
每天一篇javascript学习小结(面向对象编程)
Nov 20 Javascript
Angular4学习笔记router的简单使用
Mar 30 Javascript
Vue插槽原理与用法详解
Mar 05 Javascript
一些你可能不熟悉的JS知识点总结
Mar 15 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
May 06 Javascript
基于vue.js仿淘宝收货地址并设置默认地址的案例分析
Aug 20 Javascript
一篇文章带你从零快速上手Rollup
Sep 07 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
php 连接mssql数据库 初学php笔记
2010/03/01 PHP
PHP设计模式之建造者模式(Builder)原理与用法案例详解
2019/12/12 PHP
JQuery+DIV自定义滚动条样式的具体实现
2013/06/25 Javascript
jQuery封装的获取Url中的Get参数示例
2013/11/26 Javascript
ie8模式下click无反应点击option无反应的解决方法
2014/10/11 Javascript
Angularjs使用directive自定义指令实现attribute继承的方法详解
2016/08/05 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
Javascript循环删除数组中元素的几种方法示例
2017/05/18 Javascript
JS判断字符串是否为整数的方法--简单的正则判断
2018/07/23 Javascript
微信小程序动态增加按钮组件
2018/09/14 Javascript
详解JS取出两个数组中的不同或相同元素
2019/03/20 Javascript
Javascript的this详解
2019/03/23 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
[45:10]NB vs Liquid Supermajor小组赛 A组胜者组决赛 BO3 第二场 6.2
2018/06/04 DOTA
[01:12:44]VG vs Mineski Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
python操作字典类型的常用方法(推荐)
2016/05/16 Python
Python import与from import使用及区别介绍
2018/09/06 Python
Django使用unittest模块进行单元测试过程解析
2019/08/02 Python
详解基于python的多张不同宽高图片拼接成大图
2019/09/26 Python
一款利用html5和css3实现的3D滚动特效的教程
2015/01/04 HTML / CSS
英国和爱尔兰的自炊式豪华度假小屋:Rural Retreats
2018/06/08 全球购物
SIMON MILLER官网:洛杉矶的生活方式品牌
2020/10/19 全球购物
高校十八大报告感想
2014/01/27 职场文书
网络工程师自荐书范文
2014/04/01 职场文书
副护士长竞聘演讲稿
2014/04/30 职场文书
办理护照工作证明
2014/10/10 职场文书
房屋租赁合同解除协议书
2014/10/11 职场文书
建筑工地资料员岗位职责
2015/04/13 职场文书
幼儿园小班班务总结
2015/08/03 职场文书
小学体育组工作总结
2015/08/13 职场文书
小学运动会入场口号
2015/12/24 职场文书
2019大学竞选班长发言稿
2019/06/27 职场文书
你为什么是穷人?可能是这5个缺点造成
2019/07/11 职场文书
python分分钟绘制精美地图海报
2022/02/15 Python
Win10服务全部禁用了怎么启动?Win10服务全部禁用解决方法
2022/09/23 数码科技