内存和JS世界

85 阅读5分钟

内存

有关的英语单词学习

单词翻译单词翻译
Operatin System操作系统,简称OSkernel内核
runtime运行时(需要的东西)compile编译
environ ment环境,简称envmemory记忆,存储
person一个人people一群人

开机与操作系统

开机与操作系统.png

  • 需要重点关注开机,通电,读取固件,存储设备,开机程序,操作系统,内存这几个词语

  • shell可以看做是你与系统之间的交互或者对话,比如windows桌面就可以是shell

打开浏览器时,内存做了什么

  1. 双击打开浏览器图标,电脑开始运行这个浏览器.exe文件

  2. 开启浏览器进程,作为主进程

  3. 主进程会开启一些辅助进程,如网络服务,GPU加速等

  4. 你每新建了一个网页都有可能会开启一个子进程

浏览器功能

  • 当你输入一个域名或IP时:发起请求,下载HTML,解析HTML,下载CSS,解析CSS,把HTML和CSS合在一起渲染页面,下载JS,解析JS,执行JS等操作。

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

  • 上面的功能模块一般各处不同的线程,(比进程更小)JS是单线程

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

  • 如果JS引擎需要修改渲染,要跨线程通讯到渲染引擎,所以DOM响应较慢

JS引擎

举例

  • Chrome 用的V8引擎,C++编写的(因为C++性能特别好)

  • 网景用的是 Spider Monkey,后被Firefox使用,C++编写的

  • Safari 用的是JavaScriptCore

  • IE用的是 Chakra (JScript 9)

  • Edge用的是Chakra(JavaScript) 现在弃用了,目前用的和Chrome一样的V8引擎

  • Node.js用的是V8引擎

JS引擎的主要功能

  • 编译:把JS代码翻译为机器能执行的字节码或机器码

  • 优化:改写代码,使之更高效 (只需要依赖引擎的优化,即使有些大牛的概念其实也不符合JS引擎自身的优化)

  • 执行:执行上面的字节码或者及其吗

  • 垃圾回收:把JS用完的内存回收,方便之后再使用

执行JS代码(其他的功能涉及知识太多,目前还没学到)

准备工作

  • 提供API:window/document/setTimeout

  • 上面的东西都不是JS自身具备的功能

  • 我们将这些功能称为运行环境 runtime env

  • 一旦把JS放进页面,就开始执行JS

  • JS代码在内存里运行,JS代码会被存储到JS引擎内存块内的代码存放区内

JS内存

瓜分内存.png

  • JS引擎内分成了好几份,每个区域会专门存储指定的数据

Stack和Heap区

  • Stack和Heap区用来存放数据,我们目前只研究它

  • Stack和Heap区不存变量名,变量名存在“不知道什么区”(不同浏览器名字不同)

  • 每种浏览器的分配规则都不一样

  • 上图不完整,还没有画(调用栈)、(任务队列)等区域

  1. Stack区特点:每个数据顺序存放

  2. Heap区特点:每个数据随机存放

规律

  • 数据分两种:非对象和对象

  • 非对象都存放在Stack 例如数字、字符串、布尔 它们都不是对象

  • 对象都存放在Heap 例如数组、函数、对象

  • 等于号总是会把右边的东西复制到左边(不存在传值和传址)

在JS代码运行前,浏览器需要准备些什么

  1. window窗口,全局对象

  2. console控制台,会挂在window上

  3. document文档,会挂在window上

  4. Object对象,会挂在window上

  5. Array数组,会挂在window上

  6. Function函数,会挂在window上

简写(后者是完整写法,但前者更好用)

  • var a = [1,2,3] 等价于 var a = new Array(1,2,3) 数组简写

  • function f(){} 等价于 var f = new Function() 函数简写

  • var person={} 等价于 var person = new Object() 对象简写

挂window的东西在任何地方都能随便用

把window用内存图画出来.png

  • window里的属性是指向了一个地址

    例如 window.console 指向了 console这个对象,在这个对象的空间里有几个方法

    例如 window.Object 指向了Object这个函数,在这个函数的空间内有几个属性

关于window

  • window变量和window对象是两个东西

  • window变量是一个容器,存放window对象的地址

  • window对象是存放在Heap里的一坨数据

  • 可以让 var x = window 证明变量 x 指向了window对象,window这个变量就可以丢掉不要了

同理

  • console和console对象不是一个东西

  • Object和Object函数对象不是一个东西

  • 前者是内存地址,后者是一坨内存

  • 比如一栋楼是window,那么window对象里的属性是房间的钥匙和对应的房间号,你拿着这个房间号的钥匙去找房间,找到的房间就是对应的函数或对象

原型

  • Object或Array有个隐藏属性,指向window,里面的prototype这个对象

  • 强调一遍,这个对象叫Prototype

  • xxx.prototype 存储了xxx这个对象的共同属性

  • 如果没有原型,写对象的时候就要把所有共同属性全部写上,会把你累死

  • 原型让我们无需重复声明共有属性(省代码、省内存)

  • 每一个对象都有隐藏属性,这里我们只重点关注首字母小写对象的隐藏属性(原型)

  • 这个隐藏属性叫__proto__

prototype__proto__的区别

  • 都存着原型的地址

  • prototype挂在函数上

  • __proto__挂在每个新生成的对象上

补充

  • 只能读到共有属性,当你改共有属性的时候因为多了一层链所以就读不到也改不到

  • 最后结果只是在当前对象上添加了一个你改的属性

补充2

假如有以下代码:

var obj = {}

var arr = [1,2,3]

那么在内存图内体现原型应该如下图

我画的内存图.jpg

图中#201地址的数组原型内还有一个__proto__隐藏属性,这个属性存放的地址是#101

因为对象原型是父级,然而#101内还有一个__proto__,这个隐藏属性存放的就是null,因为没有比他更高的父级了