【JavaScript】内存图与JS世界

230 阅读4分钟

一、操作系统的常识

术语中英文对照

  • Operating System 操作系统OS
  • runtime 运行时(需要的东西)
  • environment 环境,简称env
  • kernel 内核
  • compile 编译
  • memory 存储、记忆

一切都运行在内存中

开机过程

接通电源---主板通电---读取主板上的固件---固件中的开机程序启动---开机程序将C盘中的操作系统加载到内存中

操作系统(以Linux为例)

加载操作系统内核---启动初始化进行,编号为1(每个进行都有编号)---启动系统服务(文件、安全、联网)---等待用户登录(账号密码登录/ssh登录)---运行shell,用户开始和操作系统对话---bash、图形化界面都是一种shell

打开浏览器后的运行过程

双击chrome图标---系统运行chrome.exe文件---chrome开启,是主进程---主进程开启一辅助服务,如网络服务、GPU加速服务---每打开一个新网页,都可能开启一个子进程

浏览器的功能

  • 发起请求,下载HTML,解析HTML,下载CSS,解析CSS,渲染界面,下载JS,解析JS,执行JS等
  • 功能模块:用户界面、渲染引擎(HTML+CSS)、JS引擎、存储等
  • 各功能模块是不同的线程,一个网页可以有多个线程(比如渲染引擎线程、JS引擎线程),线程之间可以通信
  • 跨线程通信:JS引擎需要修改HTML或CSS---JS引擎跨线程影响渲染引擎,跨线程通信比较慢(DOM操作慢)

二、JS引擎

JS引擎分类

  • chrome:V8引擎,C++编写
  • 网景:SpiderMonkey,后被Firefox使用,C++编写
  • Safari:JavaScriptCore
  • IE:Chakra(Jscript9)
  • Edge:Chakra(JavaScript)
  • Node.js:V8

主要功能

  • 编译:把JS代码翻译为机器可以执行的字节码或机器码
  • 优化:改写代码,使其更高效
  • 执行:执行上面的字节码或机器码
  • 垃圾回收:把JS用完的内存回收,方便之后再次使用

三、JS代码的执行

准备工作

  • 浏览器为JS提供一些API:window对象/document/setTimeout
  • 以上都不是JS自带的功能,我们将这些功能成为运行环境 runtime env

JS代码在哪里运行?

内存。JS代码被加载到哪一块内存?请继续阅读剩下内容:)

四、内存图

内存的瓜分示意图

红色区域

作用

专门用来存放数据,变量名不在此区域,在存放变量的区域

红色区域还分Stack区和Heap区

  • Stack区特点:每个数据顺序存放
  • Heap区特点:每个数据随机存放

Stack区和Heap区举例

代码

let a = 1;
let b = a;
let person = {name:'lu',child:{name:'zhou'}};
let person2 = person;

变量与对应的值的存储示意图

规律

  • 数据分两种:非对象和对象
  • 非对象存在Stack区,对象存在Heap区
  • “=”总是会直接将右边的内容复制到左边(不存在传值和传址)

五、原型

JS需要浏览器为它提供window对象

还需要以下对象(全部挂到window上,即window.xxx)

  • 得有控制台console,window.console
  • 得有文件document,window.document
  • 得有创建对象的操作,var person = {} 等价于 var person = new Object()
  • 得有创建数组的操作,var a = [1,2,3] 等价于 var a = new Array(1,2,3)
  • 得有创建函数的操作,function f(){} 等价于 var f = new Function()

为什么都要挂在window上?

因为挂在window上的东西随处可用,而且使用时可以省略window,比如window.console等价于console
下图是window在内存中的实际存放方式

关于window的一些细节(变量和对象是不同的两个东西)

  • window变量是一个容器(存放于图中的变量存放区),存放window对象的地址(存放于Heap区中)
  • window变量的地址存放于Stack区,可以用x = window将变量x的地址指向window的地址,此时x等价于window

六、JS世界

每个对象都有一个隐藏属性

叫做_proto_,它指向原型,原型里包含了共有属性

window.Object.prototype的用处

window.Object.prototype是原型,其包含了每个对象共有的属性,比如Object.toString

  • Object.prototype 保存了一个对象的地址,这个对象包含了所有普通对象的共有属性,叫做对象的原型
  • Array.prototype 保存了一个对象的地址,这个对象包含了是所有数组的共有属性,叫做数组的原型
  • Function.prototype 保存了一个对象的地址,这个对象包含了是所有函数的共有属性,叫做函数的原型
  • Function.prototype 保存了一个对象的地址,这个对象包含了是所有函数的共有属性,叫做函数的原型

__proto__和prototype的区别

  • 都存着原型的地址
  • prototype挂在函数上
  • __proto__挂在每个新生成的对象上

一个画图小练习

如下代码

var obj = {};
var arr = [1,2,3];

请画出 obj、arr 与 window、Object 和 Array 的关系