有趣的JS存储 连等问题
五个月不见了,你是不是和我一样又帅了,今天我们先来看一道经典的关于JS存储的题目,来一场紧张又刺激的脑内吃鸡大战吧:
var a = {n:1};
a.x = a = {n:2};
console.log(a.x);
console.log(a);·
问输出?
想必大家心中都有答案了 ...
结果很显然是有趣的,

到这里有部分现场观众朋友就问了,这特喵咋undefined?不是赋值了吗?别急先别骂人,往下看:
这题目某讯课堂的老师是说考的是学生对连续赋值运算的理解,这说得有点玄学了:
网上也有很多的理解:
我们先将代码这样修改:
a.x = a = {n:2}; ---- > a = a.x = {n:2};

结果显然是一致的,不论是先给 a 赋值还是先给 a.x 赋值结果都是一致的,
查了一些资料后,得知这等式中 . 的优先级别是最高的,
因此这题的思路:
JS会把变量存到栈中,而对象则会存在堆中,

1.第一行代码:变量 a 的指针指向堆栈;
2.第二行代码:a.x = a = {n:2}; 堆1中的变量对像X指向堆2 { n:2 }, 接着给a赋值 a={n:2} ,a的指针被改变指向堆2,然后堆1没有被指针指向,被GC回收,因此输出的 a.x 是underfinde 而 a 的值是 {n:2};
理解上述代码只需要稍微理解一下js变量储存:
大家都知道,JavaScript中的变量类型分为两种,一种是基本数据类型,包括:undefined,null,Number,String,Boolean,另外一种就是对象。
两种数据类型的存储方式在JS中也有所不同。
另外,内存分为栈区(stack)和堆区(heap),然后在JS中开发人员并不能直接操作堆区,堆区数据由JS引擎操作完成,那这二者在存储数据上到底有什么区别呢?
一幅图告诉你:

JS中变量的定义在内存中包括三个部分:
- 变量标示 (比如上图中的Str,变量标示存储在内存的栈区)
- 变量值 (比如上面中的Str的值souvenir或者是obj1对象的指向堆区地址,这个值也是存储在栈区)
- 对象 (比如上图中的对象1或者对象2,对象存储在堆区)
也就是说,对于基本数据类型来说,只使用了内存的栈区。
我们再做一个有趣的改动:
var a = {n:1};
var b=a;
a.x = a = {n:2};
console.log(a.x);
console.log(a);
console.log(b);
console.log(b.x);

可以看到我们并没有对 b 进行操作但是 b.x 等于{n:2},这是一个被操作过的值,就如上述可知 b的指针指向堆1,所以堆没有被回收,而被显示出来了 ~
从这么一个简单你是否对 JS存储机制有了新的认识呢 ~
欢迎大佬们的指正和各种蹂躏调教 ~~~
感谢部分摘要的作者 :https://www.cnblogs.com/souvenir/p/4969565.html
有趣的JS存储 连等问题的更多相关文章
- 【前端词典】4 个实用有趣的 JS 特性
前言 最近在学习的过程中发现了我之前未曾了解过的一些特性,发现有些很有趣并且在处理一些问题的时候可以给我一个新的思路. 这里我将这些特性介绍给大家. 4 个有趣的 JS 特性 利用 a 标签解析 UR ...
- 一个有趣的js隐式转换的问题
一个有趣的js隐式转换的问题 在chrome的控制台中打印一下表达式 [] + {} //结果为 [object object] 然后调整顺序打印 {} + [] //结果为 0 然后将两个表达式组合 ...
- vue.js存储--localStorage
//list例子:绑定从localStorage中读取的数据,动态添加list并监听将数据变化存储在localStorage中,绑定点击事件改变样式, 页面 data数据: input_name:'' ...
- 一道有趣的JS问题
function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { al ...
- JS存储cookie读取cookie删除cookie详细用法
假设有这样一种情况,在某个用例流程中,由A页面跳至B页面,若在A页面中采用JS用变量temp保存了某一变量的值,在B页面的时候,同样需要使用JS来引用temp的变量值,对于JS中的全局变量或者静态变量 ...
- JS 存储
1. 描述cookie ,sessionStorage 和 localStorage 的区别? cookie : 本身用于客户端和服务器端通信, 但是有本身存储的功能,就被‘借用’ 使用documen ...
- JS 有趣的JS
一. var arr = []; for (var i = 0; i < 3; i++) { arr[i] = function() { console.log(i+'__') // 3 3 3 ...
- 一些有趣的 js 包
https://github.com/octalmage/robotjs Node.js桌面自动化.控制鼠标,键盘和屏幕. http://robotjs.io
- 有趣的 Mysql 存储引擎
Mysql 提供了一套统一的应用开发模型和核心 API,因此,尽管不同的存储引擎拥有不同的特性,不过对于开发人员,应用操作都是完全透明的.应用层的连接并不直接访问存储引擎层,而是访问 Mysql 提供 ...
随机推荐
- CoreData使用
1.如果想创建一个带有coreData的程序,要在项目初始化的时候勾选中 2.创建完成之后,会发现在AppDelegate里多出了几个属性,和2个方法 <span style="fon ...
- Python视频教程
Python这门语言相对学起来是简单点的,尤其对于测试人员来说,如果达到可以写自动化测试脚本的程度的话,学些基础就是可以的.那么在网上也是有很多资源的,各种培训的视频.作为一名过来人(哈哈),或者说是 ...
- Loadrunner脚本自动关联和手动关联
关于Loadrunner关联一.什么时候需要关联 1.关联的含义 关联(correlation):在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服 ...
- ssh整合 小例子
实现了用户的查插删改操作. 原理:struts负责接收.分发请求.spring采用面向接口编程的思想整合整体框架,负责连接数据库.hibernate负责操作数据库语言. 思路: 1.配置struts的 ...
- Git学习笔记 - Git安装
Git安装(Windows) 从 https://git-for-windows.github.io/ 下载Git,下载完成,双击安装,一路选择默认设置即可. 注意:选择使用git的命令行模式,选择默 ...
- (转)vim 访问系统剪贴板
原文出处:http://vim.wikia.com/wiki/Accessing_the_system_clipboard Please review this tip: This tip was i ...
- [HNOI 2010] 弹飞绵羊
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2002 [算法] LCT动态维护森林连通性 时间复杂度 : O(NlogN ^ 2) ...
- vue 表单验证省市县三联动
<el-col :span="24"> <el-form-item label="所在地区" prop="region" ...
- Linux--top命令查看系统状态,所有值讲解
Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息.通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 一.top ...
- Android开发—— 传递数据
一:使用静态变量传递数据 (1)静态变量传递数据,在目标Activity中声明静态变量,然后使用setText()方法将静态变量的值导出即可: (2)静态变量传递数据,在主Activity中对目标Ac ...