内存图和 JS 世界

JS 小知识:

JavaScript 的历史

Javascript 诞生记

Javascript 的 10 个设计缺陷

操作系统常识

一切都运行在内存里

开机

  • 操作系统在 C 盘里(macOS 的在根目录下多个目录里)
  • 当你按下开机键,主板通电,开始读取固件
  • 固件就是固定在主板上的存储设备,里面有开机程序
  • 开机程序会将文件里的操作系统加载到内存中运行

操作系统(以 Linux 为例)

  • 首先加载操作系统内核
  • 然后启动初始化进程,编号为 1,每个进程都有编号
  • 启动系统服务: 文件、安全、联网
  • 等待用户登录: 输入密码登录/ssh 登录
  • 登录后,运行 shell,用户就可以和操作系统对话了
  • bash 是一种 shell,图形化界面可认为是一种 shell

打开浏览器

chrome.exe

  • 你双击 Chrome 图标,就会运行 chrome.exe 文件
  • 开启 Chrome 进程,作为主进程
  • 主进程会开启一些辅助进程,如网络服务、GPU 加速
  • 你每新建一个网页,就有可能会开启一个子进程

浏览器的功能

  • 发起请求,下载 HTML,解析 HTML,下载 CSS,解析 CSS,渲染界面,下载 JS,解析 JS,执行 JS 等

  • 功能模块: 用户界面,渲染引擎、JS 引擎、存储等

  • 上面的功能模块一般各处于不同的线程(比进程小)

  • 如果进程是车间,那么线程就是车间里的流水线

    进程与线程的一个简单解释 - 阮一峰的网络日志

JS 引擎

JS 引擎举例

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

主要功能

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

内存图

瓜分内存

红色区域

作用

  • 红色专门用来存放数据,我们目前只研究该区域
  • 红色区域并不存变量名
  • 每种浏览器的分配规则并不一样
  • 上图的区域并不完整,还没有画调用栈、任务队列等区域

Stack 和 Heap

  • 红色区域分为 Stack 栈和 Heap 堆
  • Stack 区特点: 每个数据顺序存放
  • Heap 区特点: 每个数据随机存放

Stack 和 Heap 举例

举例

var a = 1
var b = a
var person = {name: 'frank’, child: {name: ‘jack’}}
var person2 = person

画出内存图如下:

规律

  • 数据分两种: 非对象和对象
  • 非对象都存在 Stack
  • 对象都存在 Heap

    数组和函数都是对象

  • =号总是会把右边的东西复制到左边

JS 开发者说要有 window

就有了 window(浏览器提供)

还要什么

要有 console

  • 于是就有了 console,并且挂到 window 上

要有 document

  • 于是就有了 document,并且挂到 window 上

要有对象

  • 于是就有了 Object,并且挂到 window 上
  • var person = {} 等价于 var person = new Object()

要有数组(一种特殊的对象)

  • 于是就有了 Array,并且挂到 window 上
  • var a = [1, 2, 3]等价于 var a = new Array(1, 2, 3)

要有函数(一种特殊的对象)

  • 于是就有了 Function, 并且挂到 window 上
  • funciton f(){} 等价于 var f = new Function()

    怎么什么都挂载 window 上?

    因为方便,挂在 window 上的东西可以再任何地方直接用

把 window 用内存图画出来

更简单的画法

一般来说,第一个字母大写会有 prototype 属性。

细节

关于 window

  • window 变量和 window 对象是两个东西
  • window 变量是一个容器,存放 window 对象的地址
  • window 对象是 Heap 里的一坨数据

    不信的话,可以让 var x = window,那么这个 x 就只想了 window 对象,window 变量就 🈚️ 了。但是这样的代码用弄晕新手,所以不要这样写。

同理

  • console 和 console 对象不是同一个东西
  • Object 和 Object 对象不是同一个东西
  • 前者是内存地址,后者是一坨内存

原型链

思考: 图里的 prototype 是干什么用的

XXX.prototype 存储了 XXX 对象的共同属性,这就是原型。

Q: 这个隐藏属性叫什么?

A: __proto__

Q: prototype__proto__区别是什么?

A: 都存着原型的地址。只不过prototype挂在函数上,__proto__挂在每个新生成的对象上

comments powered by Disqus