Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] 第127天 JavaScript有几种类型值?能否画出它们的内存图? #1094

Open
haizhilin2013 opened this issue Aug 20, 2019 · 7 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

第127天 JavaScript有几种类型值?能否画出它们的内存图?

@haizhilin2013 haizhilin2013 added the js JavaScript label Aug 20, 2019
@LinStan
Copy link

LinStan commented Aug 21, 2019

基本类型:Number Boolean Null Undefined String Symbol
引用类型:Object

其中基本类型都是存在于栈内存中的,会为其分配固定大小的内存。
引用类型则是在栈内存中保存一个自己的地址索引,实际引用类型的值存在于堆内存中。

@wuliTaoLeo
Copy link

栈:原始数据类型(Undefined Null Boolean Number String)
堆:引用数据类型(对象、数组、函数)

原始数据:

image

引用数据:
image

@liuxiaole
Copy link

你们从哪里 copy 的 JS 原始数据类型存放在栈上的?好奇去搜索了一下,发现果然各种 CSDN 博客乱说一气。

如果 JS 基本类型都保存在栈上,那怎么解释调用栈弹出后,局部变量仍然可以被闭包访问?还有说 JS string 也是在栈内存的,又说栈上的变量都是固定分配大小的,are you sure? 从 HTTP response 获得的一段字符串会在栈上?从 Blob / ArrayBuffer 里读到的字符串怎么固定分配大小?

你讲值类型和引用类型可以,但是不要讲堆内存和栈内存。很反感把堆内存和栈内存的概念引入 JS 中,因为这些概念在 JS 中根本不适用。C/C++有这种概念,因为他们直接在操作系统中运行,操作系统给程序分配内存的时候确实是分栈内存还是堆内存的,他们标准就有 sizeof 这种求变量大小的操作符,有分配 / 释放内存的 API。Java 语言虽然也有 GC ,但也分这两种内存,但这个时候,对于 Java 程序本身来说内存是 JVM 来管理的,所谓的栈内存堆内存是 JVM 定义下的,并不是操作系统管理下的概念。

回头说 JS 的情况,ES 标准从来没有提到 JS 中哪些数据类型要以栈内存的形式存储,哪些是堆内存存储。ES6 标准里提到的是执行上下文(execution context)、词法环境(Lexical Environment)、变量环境(Variable Environment)、环境记录(Environment Records)。环境记录就是那个用来保存标识符和变量值的映射。那请问这个变量值是堆内存还是栈内存呢?你说 string 是基本类型所以是分配在栈上的,你去了解一下 V8 对 string 的优化,你的内存图恐怕没那么简单能画对。原始数据类型还包括一个 Symbol 吧,那请问一个 symbol 变量在栈上的内存是怎样的?占几个字节?

总结:你根本不需要去探究 JS 中的变量是保存在堆里还是栈里,非要说那就是全部都是在堆里。

@Eleven-SL
Copy link

类型值共有7种: 数值、字符串、布尔值、ES6 新出的 Symbol Null Undefined 对象(Object、Function、Array)

@xiao-fe
Copy link

xiao-fe commented Jun 22, 2020

你们从哪里 copy 的 JS 原始数据类型存放在栈上的?好奇去搜索了一下,发现果然各种 CSDN 博客乱说一气。

如果 JS 基本类型都保存在栈上,那怎么解释调用栈弹出后,局部变量仍然可以被闭包访问?还有说 JS string 也是在栈内存的,又说栈上的变量都是固定分配大小的,are you sure? 从 HTTP response 获得的一段字符串会在栈上?从 Blob / ArrayBuffer 里读到的字符串怎么固定分配大小?

你讲值类型和引用类型可以,但是不要讲堆内存和栈内存。很反感把堆内存和栈内存的概念引入 JS 中,因为这些概念在 JS 中根本不适用。C/C++有这种概念,因为他们直接在操作系统中运行,操作系统给程序分配内存的时候确实是分栈内存还是堆内存的,他们标准就有 sizeof 这种求变量大小的操作符,有分配 / 释放内存的 API。Java 语言虽然也有 GC ,但也分这两种内存,但这个时候,对于 Java 程序本身来说内存是 JVM 来管理的,所谓的栈内存堆内存是 JVM 定义下的,并不是操作系统管理下的概念。

回头说 JS 的情况,ES 标准从来没有提到 JS 中哪些数据类型要以栈内存的形式存储,哪些是堆内存存储。ES6 标准里提到的是执行上下文(execution context)、词法环境(Lexical Environment)、变量环境(Variable Environment)、环境记录(Environment Records)。环境记录就是那个用来保存标识符和变量值的映射。那请问这个变量值是堆内存还是栈内存呢?你说 string 是基本类型所以是分配在栈上的,你去了解一下 V8 对 string 的优化,你的内存图恐怕没那么简单能画对。原始数据类型还包括一个 Symbol 吧,那请问一个 symbol 变量在栈上的内存是怎样的?占几个字节?

总结:你根本不需要去探究 JS 中的变量是保存在堆里还是栈里,非要说那就是全部都是在堆里。

你们从哪里 copy 的 JS 原始数据类型存放在栈上的?好奇去搜索了一下,发现果然各种 CSDN 博客乱说一气。

如果 JS 基本类型都保存在栈上,那怎么解释调用栈弹出后,局部变量仍然可以被闭包访问?还有说 JS string 也是在栈内存的,又说栈上的变量都是固定分配大小的,are you sure? 从 HTTP response 获得的一段字符串会在栈上?从 Blob / ArrayBuffer 里读到的字符串怎么固定分配大小?

你讲值类型和引用类型可以,但是不要讲堆内存和栈内存。很反感把堆内存和栈内存的概念引入 JS 中,因为这些概念在 JS 中根本不适用。C/C++有这种概念,因为他们直接在操作系统中运行,操作系统给程序分配内存的时候确实是分栈内存还是堆内存的,他们标准就有 sizeof 这种求变量大小的操作符,有分配 / 释放内存的 API。Java 语言虽然也有 GC ,但也分这两种内存,但这个时候,对于 Java 程序本身来说内存是 JVM 来管理的,所谓的栈内存堆内存是 JVM 定义下的,并不是操作系统管理下的概念。

回头说 JS 的情况,ES 标准从来没有提到 JS 中哪些数据类型要以栈内存的形式存储,哪些是堆内存存储。ES6 标准里提到的是执行上下文(execution context)、词法环境(Lexical Environment)、变量环境(Variable Environment)、环境记录(Environment Records)。环境记录就是那个用来保存标识符和变量值的映射。那请问这个变量值是堆内存还是栈内存呢?你说 string 是基本类型所以是分配在栈上的,你去了解一下 V8 对 string 的优化,你的内存图恐怕没那么简单能画对。原始数据类型还包括一个 Symbol 吧,那请问一个 symbol 变量在栈上的内存是怎样的?占几个字节?

总结:你根本不需要去探究 JS 中的变量是保存在堆里还是栈里,非要说那就是全部都是在堆里。

你好,js变量存储官方资料在哪可以看?谢谢!

@MsEcho
Copy link

MsEcho commented Feb 3, 2021

你们从哪里 copy 的 JS 原始数据类型存放在栈上的?好奇去搜索了一下,发现果然各种 CSDN 博客乱说一气。

如果 JS 基本类型都保存在栈上,那怎么解释调用栈弹出后,局部变量仍然可以被闭包访问?还有说 JS string 也是在栈内存的,又说栈上的变量都是固定分配大小的,are you sure? 从 HTTP response 获得的一段字符串会在栈上?从 Blob / ArrayBuffer 里读到的字符串怎么固定分配大小?

你讲值类型和引用类型可以,但是不要讲堆内存和栈内存。很反感把堆内存和栈内存的概念引入 JS 中,因为这些概念在 JS 中根本不适用。C/C++有这种概念,因为他们直接在操作系统中运行,操作系统给程序分配内存的时候确实是分栈内存还是堆内存的,他们标准就有 sizeof 这种求变量大小的操作符,有分配 / 释放内存的 API。Java 语言虽然也有 GC ,但也分这两种内存,但这个时候,对于 Java 程序本身来说内存是 JVM 来管理的,所谓的栈内存堆内存是 JVM 定义下的,并不是操作系统管理下的概念。

回头说 JS 的情况,ES 标准从来没有提到 JS 中哪些数据类型要以栈内存的形式存储,哪些是堆内存存储。ES6 标准里提到的是执行上下文(execution context)、词法环境(Lexical Environment)、变量环境(Variable Environment)、环境记录(Environment Records)。环境记录就是那个用来保存标识符和变量值的映射。那请问这个变量值是堆内存还是栈内存呢?你说 string 是基本类型所以是分配在栈上的,你去了解一下 V8 对 string 的优化,你的内存图恐怕没那么简单能画对。原始数据类型还包括一个 Symbol 吧,那请问一个 symbol 变量在栈上的内存是怎样的?占几个字节?

总结:你根本不需要去探究 JS 中的变量是保存在堆里还是栈里,非要说那就是全部都是在堆里。

红宝书第四章小结里写了“基本类型值在内存中占固定大小的空间,因此被保存在栈内存中”、“引用类型的值是对象,保存在堆内存中”,这里说的“固定大小”应该是指基本类型的值的大小在初始化的时候是固定,不能修改的意思吧。

@xiaoqiangz
Copy link

基本类型: string、number、boolean、Undefined、null、Symbol、BigInt
引用类型:object、array、function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests

8 participants