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变量存储浅析(二)的更多相关文章

  1. JavaScript变量存储浅析(一)

    Hello! 上一篇关于JS中函数传参(http://www.cnblogs.com/souvenir/p/4969092.html)的介绍中提到了JS的另外一个基本概念:JS变量存储, 今天我们就用 ...

  2. JavaScript变量存储浅析

    var test=100; function foo(){ console.log(test);//undefined var test=200; console.log(test); } 我们明明定 ...

  3. javascript变量浅析

    变量声明 javascript 使用var + 变量名 声明变量,因为javascript是弱类型语言, 所有我们可以随意更改已有变量的类型. var b=1; b='2', 另外不同于c#中的var ...

  4. JavaScript快速入门(二)——JavaScript变量

    变量声明 JavaScript的变量声明分为显式声明跟隐式声明. 显式声明 即带var关键字声明,例如 var example = example; 要注意JavaScript里面声明的关键字只有fu ...

  5. 以太坊系列之十二: solidity变量存储

    solidity中变量的存储 变量存储主要分为两个区域,一个是storage(对应指定是SLOAD,SSTORE),一个是Memory(MLOAD,MSTORE), 这和普通编程语言的内存模型是不一样 ...

  6. JavaScript 变量

    一,JavaScript 变量(存储信息的容器) 与代数一样,JavaScript 变量可用于存放值(比如 x=2)和表达式(比如 z=x+y). 变量可以使用短名称(比如 x 和 y),也可以使用描 ...

  7. JavaScript基本语法(二)

    上篇博文写到JavaScript的数据类型.JavaScript包括了字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null).未 ...

  8. JavaScript垃圾回收(二)——垃圾回收算法

    一.引用计数(Reference Counting)算法 Internet Explorer 8以下的DOM和BOM使用COM组件所以是引用计数来为DOM对象处理内存,引用计数的含义是跟踪记录每个值被 ...

  9. 2015第35周五JavaScript变量

    java语言里有一句很经典的话:在java的世界里,一切皆是对象. Javascript虽然跟java没有半点毛关系,但是很多会使用javascript的朋友同样认为:在javascript的世界里, ...

随机推荐

  1. i系列标准-互联网周刊

    原文:http://www.enet.com.cn/article/2019/0429/A20190429062899.html 传统意义上的规模.现代意义上的工具时代感.永远不会改变的最高意义上的使 ...

  2. 《Effective Java》第2章 对所有对象都通用的方法

    第10条:覆盖equals时,请遵守通用约定 1.使用==来比较两个对象的时候,比较的是两个对象在内存中的地址是否相同(两个引用指向的是否为同一个对象):Object中定义的equals方法也是这样比 ...

  3. IDEA强制清除Maven缓存

    目录 重新导入依赖的常见方式 存在的问题 彻底清除IDEA缓存的方式 重新导入依赖的常见方式 下面图中的刷新按钮,在我的机器上,并不能每次都正确导入pom.xml中写的依赖项,而是导入之前pom.xm ...

  4. vscode-tab按键失效变为切换功能的解决方法

    有一种可能是无意中按到了ctrl+m,此时VSCode右下角会出现Tab Moves focus的字样,如下: 用ctrl + m 可以切换两种状态.没有Tab Moves focus字样的时候,就是 ...

  5. Laravel 登录后跳转回登录前浏览的页面

    一.经过 Auth 中间件检查后跳转至登录页面 也就是没有通过 auth 中间件的认证检查,被 auth 中间件拦截后跳转至登录页面.这种情况下,Laravel 默认会在用户登录成功后自动跳转回登录前 ...

  6. Docker容器部署Mysql数据库服务器

    本节会用到的Docker命令如下: docker images 查看mysql镜像id docker run -d -p xxxxxxxxxxxxxxx/zhufc/mysql:v2 通过镜像生成 启 ...

  7. find和grep的使用

    1.find命令的使用 在Linux中可以使用find命令在指定的目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名,当使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目 ...

  8. JS系列:数据类型详细讲解

    ctrl+B加粗 ### 数据类型: - 1.number数字类型 NaN:not a number 不是一个数 ,但他是数字类型 isNaN:检测当前值是否不是有效数字,返回true代表不是有效数字 ...

  9. [转载]ROS开发环境之Qt Creator

    ROS开发环境之Qt Creator(http://my.phirobot.com/blog/2013-12-ros_ide_qtcreator.html) Created at: 2013-12-2 ...

  10. [转帖]Flink(一)Flink的入门简介

    Flink(一)Flink的入门简介 https://www.cnblogs.com/frankdeng/p/9400622.html 一. Flink的引入 这几年大数据的飞速发展,出现了很多热门的 ...