js中的数据、内存和变量

  今天就说一说js中的数据、内存和变量吧。之前一直对变量关注的比较多,而忽视了内存和数据以及它们三者之间的关系,今天就在这里补一波。

一、js中的数据指的是什么?

  数据在人们眼中向来都是一个非常抽象的事物,它无处不在,但是我们总是不知道怎么去描述它。而js中的数据,我认为它是指:在内存中可读的, 可传递的、保存了特定信息的“东西”,是我们在内存中所操作的目标。一个函数是数据、一个常量是数据、一个对象也是数据。

二、js中的变量

  说完了数据,接下来说一下变量。变量这个词相信大家都听说过无数次了,有些人可能会说:“变量不就是通过var 声明的一个东西吗?”这样理解并不是完全正确,例如,我们不使用var,直接a = 1,这样也会声明一个变量。
  我所理解的变量:变量就是在程序运行过程中它的值允许改变的量。 一个变量对应一块小内存, 它的值保存在此内存中。变量常常包含两部分:变量名和变量的值。

三、js中的简单内存模型

  唉?你说了这么多到底什么是内存啊?
  我们可以把内存理解为*内存条通电后产生的(临时的)存储空间。一块内存包含2个方面的数据:内部存储的数据和地址值数据。在js的内存模型中内存分为可以分为三个部分:
常量池:存放常量的内存区域。
栈空间:存放全局变量和局部变量的内存区域。
堆空间: 存放对象等复杂数据类型的内存区域。
听起来是不是很抽象,下面上图:
这里写图片描述
我们存放一个常量时,将其存放在常量池中,保存常量名称和常量的值。在这里主要是说一下栈空间和堆空间。栈空间用来存放全局变量和局部变量,如果该变量是基本数据类型,那么栈空间存储该变量的名称和值。例如,var a = 1; 我们会在栈空间中开辟一块新的内存,存放变量的名称a和变量的值1。如果该变量是复杂数据类型(对象),那么栈空间存放变量名称和该对象在堆空间中的地址值。例如,var b = {n : 1,m : 2}; 我们会在堆空间中开辟一块内存存放对象{n : 1,m : 2},同时在栈中开辟一块内存空间存放变量名b和该对象在堆空间的地址值0x123。
了解了这JavaScript简单的内存结构,我们下面来看一看几个有趣的代码片段吧。

四、几个有趣的代码片段
4.1、js中,变量的比较是栈中存放该变量的内存的内容(值或地址值)的比较,对存放基本数据类型的变量来说,栈中存放的是该变量的名称和值;对存放复杂数据类型(对象)的变量来说。栈中存放的是该变量的名称和地址值,而对象的具体内容存放在堆中。

下面上代码一:

var obj1 = {n : 1};
var obj2 = {n : 1};
console.log(obj1 === obj2);//false

咦,为什么obj1和obj2的内容看上去明明相等,但是会返回false呀?这就涉及到了js内存模型的知识。参考上面的js内存模型图,我们可以看到,在执行var obj1 = {n : 1};时,会在堆中开辟一个新的空间存放obj1对象的具体内容,同时把新空间的地址存放在对应的栈中,执行第二行时同理。所以obj1和obj2保存的其实是两个不同的地址值,所以它们不可能相等。
如果把代码改成下面这个样子:

var obj1 = {n : 1};
var obj2 = obj1;
console.log(obj1 === obj2);//true

执行第一行的时候,原理同上。但是执行第二行时,我们将obj1的地址值赋值给了obj2,此时变量obj1和obj2在栈中保存的值均为对象{n:1}的地址值,所以它们相等。
接下来,我们来看一道比较有趣的题目!!!
代码二:

var a = {n : 1};
var b = a;
a.x = a = {n : 2};
console.log(a.x);//undefined
console.log(b.x);//{ n: 2 }

如果你的结果和上面一样,那么恭喜你,你已经掌握了js简单的内存模型。为什么会是这样子的结果呢?我们不妨一步一步来画图一探究竟(假设左边为栈,右边为堆)。
执行var a = {n : 1};时,先在堆空间中开辟一块内存空间,存放对象a,同时在栈中存放该对象在堆中的地址。
这里写图片描述
执行第二行时,在栈中新开辟了一块内存空间用来存放b,由b=a可知b和a的保存的地址值相等,均为0x123。这里一定要注意,是将变量a的内容(地址值)赋值给b。此时a和b都指向堆空间中的同一块内存。
这里写图片描述
接下来最关键的东西要来了,那就是第三行代码。根据js中运算符的优先级可知,“.”的优先级高于“=”,所以会先执行a.x,此时虽然并没有给x赋值,但是还是会给a指向的对象添加一个属性x,值为undefined。
这里写图片描述
接下来开始执行“=”,从右至左开始执行,那么首先会执行a = {n : 2},此时在堆空间中开辟了一个新的内存空间用来存放{n : 2},假设地址值为0x456,并且修改了变量a的内容(地址值),由原来的0x123变成了0x456。
这里写图片描述
最后,执行a.x=a。需要注意的是,此时左右两边的a并不相同,右边的为新产生的a,其值为0x456,而左边的a由于一直保持着引用,并没有被销毁,所以地址一直是0x123,那么问题就解决了,a.x = a就是把对象b中的属性x的值赋值为{n : 2},到这里为止,问题就解决了。
这里写图片描述

总结

1 .内存,数据, 变量三者之间的关系:
内存是容器, 用来存储不同数据,变量是内存的标识, 通过变量我们可以操作(读/写)内存中的数据 。
2.js中对变量的操作都是对栈中变量的内容(值或地址)进行操作,判断基本数据类型是否相等时,时对栈中变量的值进行比较,判断对象是否相等时比较的是栈中变量存放的地址值是否相等。
3.js简单内存模型。

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值