理解Javascript_01_理解内存分配原理分析


Posted in Javascript onOctober 11, 2010

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

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

var arr = []; //创建一个栈 
arr.push("apple");//压入元素"apple" ["apple"] 
arr.push("orange");//压入元素"orange" ["apple","orange"] 
arr.pop();//弹出"orange" ["apple"] 
arr.push("banana");//压入元素"banana" ["apple","banana"]

我们来看一下,与之对应的内存图:
理解Javascript_01_理解内存分配原理分析
原始值是存储在栈中的简单数据段,也就是说,他们的值直接存储在变量访问的位置。
堆是存放数据的基于散列算法的数据结构,在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,"jxl",22);

然后我们来看一下内存分析图:
理解Javascript_01_理解内存分配原理分析
变量num,bol,str为基本数据类型,它们的值,直接存放在栈中,obj,person,arr为复合数据类型,他们的引用变量存储在栈中,指向于存储在堆中的实际对象。

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

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

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

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

总结:

程序很简单,但它是一切的根本,基础是最重要的,因为摩天大厦也是一块砖一块瓦的搭建起来的。
内存是程序执行的根本,搞懂了内存,就等于搞懂了一切。
心血之作,鼓励一下自已,加油!

参考:
JavaScript高级程序设计

Javascript 相关文章推荐
分享20款好玩的jQuery游戏
Apr 17 Javascript
JavaScript中的Number数字类型学习笔记
May 26 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 Javascript
Angular2 路由问题修复详解
Mar 01 Javascript
微信小程序 图片宽度自适应的实现
Apr 06 Javascript
微信小程序之数据双向绑定与数据操作
May 12 Javascript
Node.js  事件循环详解及实例
Aug 06 Javascript
Redux 和 Mobx的选择问题:让你不再困惑!
Sep 18 Javascript
jQuery实现的回车触发按钮事件功能示例
Mar 25 jQuery
小程序实现单选多选功能
Nov 04 Javascript
基于canvas实现手写签名(vue)
May 21 Javascript
js实现点击烟花特效
Oct 14 Javascript
javascript getElementsByClassName实现代码
Oct 11 #Javascript
javascript Array.prototype.slice使用说明
Oct 11 #Javascript
javascript 伪数组实现方法
Oct 11 #Javascript
javascript forEach通用循环遍历方法
Oct 11 #Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
Oct 11 #Javascript
JavaScript isArray()函数判断对象类型的种种方法
Oct 11 #Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
Oct 11 #Javascript
You might like
eWebEditor v3.8 商业完整版 (PHP)
2006/12/06 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
2011/10/29 PHP
VIM中设置php自动缩进为4个空格的方法详解
2013/06/14 PHP
thinkphp命名空间用法实例详解
2015/12/30 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
javascript 面向对象全新理练之原型继承
2009/12/03 Javascript
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
常见JS效果之图片减速度滚动实现代码
2011/12/08 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
jquery事件preventDefault()方法用法实例
2015/01/16 Javascript
Javascript实现获取及设置光标位置的方法
2015/07/21 Javascript
微信小程序开发图片拖拽实例详解
2017/05/05 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
2018/07/06 Javascript
通过封装scroll.js 获取滚动条的值
2018/07/13 Javascript
微信小程序动画(Animation)的实现及执行步骤
2018/10/28 Javascript
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
2019/06/06 jQuery
使用微信SDK自定义分享的方法
2019/07/03 Javascript
vue图片加载失败时用默认图片替换的方法
2019/08/29 Javascript
vue和小程序项目中使用iconfont的方法
2020/05/19 Javascript
JS如何定义用字符串拼接的变量
2020/07/11 Javascript
[00:02]DOTA2新版本使用PA至宝后暴击展示
2014/11/19 DOTA
[01:07:53]RNG vs VG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python之模拟鼠标键盘动作具体实现
2013/12/30 Python
Python Matplotlib库入门指南
2015/05/18 Python
深入理解python中sort()与sorted()的区别
2018/08/29 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
python热力图实现简单方法
2021/01/29 Python
html5使用window.postMessage进行跨域实现数据交互的一次实战
2021/02/24 HTML / CSS
海信商城:海信电视、科龙空调、容声冰箱官方专卖
2017/02/07 全球购物
简述数据库的设计过程
2015/06/22 面试题
领导检查欢迎词
2014/01/14 职场文书
班级心理活动总结
2014/07/04 职场文书
学习杨善洲同志先进事迹心得体会
2016/01/23 职场文书
简单谈谈Python面向对象的相关知识
2021/06/28 Python
15个值得收藏的JavaScript函数
2021/09/15 Javascript