JavaScript变量存储浅析(二)
Hello,上一篇(http://www.cnblogs.com/souvenir/p/4969399.html)我们简单的分享了JS中的变量存储原理,但是并未结束,我们漏掉了什么。
对了,就是关于对象的存储。
大家都知道,JavaScript中的变量类型分为两种,一种是基本数据类型,包括:undefined,null,Number,String,Boolean,另外一种就是对象。
两种数据类型的存储方式在JS中也有所不同。
另外,内存分为栈区(stack)和堆区(heap),然后在JS中开发人员并不能直接操作堆区,堆区数据由JS引擎操作完成,那这二者在存储数据上到底有什么区别呢?
我们简单的通过下面这张图来分析:

JS中变量的定义在内存中包括三个部分:
- 变量标示 (比如上图中的Str,变量标示存储在内存的栈区)
- 变量值 (比如上面中的Str的值souvenir或者是obj1对象的指向堆区地址,这个值也是存储在栈区)
- 对象 (比如上图中的对象1或者对象2,对象存储在堆区)
也就是说,对于基本数据类型来说,只使用了内存的栈区。
对于上一篇中提到的问题来说,
var a = 100;
func();
function func(){
console.log(a);
var a=200;
console.log(a);
}
在JS预加载阶段,JS引擎只是在内存的栈区为每个变量分配了内存,指定了标示符,并未为其指定值。
等到JS执行期才会为其赋值。
现在我们再来看对象变量的问题就比较清楚了,例如下面的:
var a=100;
var obj1={
attr:'hello'
}; func(a,obj1); function func(num,obj){
var a2=num;
a2=200; var obj2=obj;
obj2.attr='hello';
} console.log(a);
console.log(obj1.attr);
我们分别定义了一个基本类型和对象类型的变量,然后在函数中对其分别执行复制操作,然后修改新变量的值。
最后的执行结果为:

对于基本数据类型,在执行第9行时,JS是把num在栈区的值,也就是100复制给了a2这个局部变量,然后在第10行又修改了a2的值,
这个操作过程并未影响到全局变量a的值。
小结:
对于对象来说,当JS执行12行的时候,实际上是把obj在栈区的值,也就是obj对象在堆区的引用地址,复制给了新的局部变量obj2,
这时候,obj2与obj实际上已经指向了同一个堆区的对象,然后obj2修改了这个对象的某个属性值。然后函数执行完毕,obj2这个局部变量没有引用将会被GC回收。
再次访问obj1这个全局变量时,其所指向的对象其实已经被修改过了。
JavaScript变量存储浅析(二)的更多相关文章
- JavaScript变量存储浅析(一)
Hello! 上一篇关于JS中函数传参(http://www.cnblogs.com/souvenir/p/4969092.html)的介绍中提到了JS的另外一个基本概念:JS变量存储, 今天我们就用 ...
- JavaScript变量存储浅析
var test=100; function foo(){ console.log(test);//undefined var test=200; console.log(test); } 我们明明定 ...
- javascript变量浅析
变量声明 javascript 使用var + 变量名 声明变量,因为javascript是弱类型语言, 所有我们可以随意更改已有变量的类型. var b=1; b='2', 另外不同于c#中的var ...
- JavaScript快速入门(二)——JavaScript变量
变量声明 JavaScript的变量声明分为显式声明跟隐式声明. 显式声明 即带var关键字声明,例如 var example = example; 要注意JavaScript里面声明的关键字只有fu ...
- 以太坊系列之十二: solidity变量存储
solidity中变量的存储 变量存储主要分为两个区域,一个是storage(对应指定是SLOAD,SSTORE),一个是Memory(MLOAD,MSTORE), 这和普通编程语言的内存模型是不一样 ...
- JavaScript 变量
一,JavaScript 变量(存储信息的容器) 与代数一样,JavaScript 变量可用于存放值(比如 x=2)和表达式(比如 z=x+y). 变量可以使用短名称(比如 x 和 y),也可以使用描 ...
- JavaScript基本语法(二)
上篇博文写到JavaScript的数据类型.JavaScript包括了字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null).未 ...
- JavaScript垃圾回收(二)——垃圾回收算法
一.引用计数(Reference Counting)算法 Internet Explorer 8以下的DOM和BOM使用COM组件所以是引用计数来为DOM对象处理内存,引用计数的含义是跟踪记录每个值被 ...
- 2015第35周五JavaScript变量
java语言里有一句很经典的话:在java的世界里,一切皆是对象. Javascript虽然跟java没有半点毛关系,但是很多会使用javascript的朋友同样认为:在javascript的世界里, ...
随机推荐
- Navicat 12.x for MySQL最新版安装破解教程(附安装包和注册机,全网独家可用
title: "Navicat 12.x for MySQL最新版安装破解教程(附安装包和注册机,全网独家可用" categories: soft tags: soft autho ...
- mac opencv 提示摄像头权限问题
通常在iOS开发下,我们的app需要在Info.plist文件中配置所需要的各种限制:如摄像头权限: 本次我们在mac下创建了一个command line 程序,并且设定是c++开发,并配置了open ...
- 018 oauth协议
1.作用 2.流程步骤 3.授权模式 4.授权码模式
- css---【vw,vh】进行自适应布局单位
在进行CSS3自适应布局,会用到 vw 和 vh 进行布局 视口单位(Viewport units) 什么是视口? 在桌面端,视口指的是在桌面端,指的是浏览器的可视区域:而在移动端,它涉及3个视口:L ...
- fgets注意事项
这是yjy的习题库,中途我在使用fgest时颇费了一点心思,特此记录一下. #include <stdio.h> #include <string.h> #include &l ...
- 阿里云环境安装K8S步骤
1. 安装docker yum install -y docker 2. 修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值 $ vim /et ...
- python |elasticsearchs操作es的例子
from elasticsearch import Elasticsearch import json import time es = Elasticsearch(['es地址:9200'],ign ...
- 调试node接口
从node服务端到浏览器端,调试node脚本,验证接口功能是否正常. 一.温故知新 https://www.cnblogs.com/camille666/p/nodejs_server.html ht ...
- 关于C#编写x86与x64程序的分析
电脑硬件CPU可以分为x86与x64, x86的机器只能安装32位的操作系统,如XP, WIN7_86, x64的机器既可以安装32位的系统,又可以安装64位的系统,只是在x64的机器上安装32位的系 ...
- lnmp+discuz使用redis缓存(待进一步研究)
一直说Redis.Redis缓存.一直不清楚怎么用.于是花点时间研究了一下,但是还没搞懂.先把大概内容记录一下,待后续继续学习 1.首先部署lnmp环境,这个我的博客有些,请自行搜索 2.给php添加 ...