JavaScript 内存图与JS世界

121 阅读3分钟

浏览器的功能

用户打开浏览器,在搜索栏输入网址,这个过程都发生了什么
浏览器发起请求,下载HTML,解析HTML,下载css,解析css,渲染界面,下载JS,解析JS,执行JS

怎么执行JS

需要功能模块
用户界面
渲染引擎
JS引擎
存储

功能模块一般处于不同的线程(比进程更小)

JS为什么可以渲染

线程之间有跨线程通信,JS通过跨线程通信,通知渲染引擎进行渲染
JS是单线程的,不能往下分
DOM操作慢,因为跨线程

JS引擎主要功能

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

内存图

瓜分内存(概念图)

作用

红色区域是数据区,专门用来存放数据
每种浏览器的存放规则不一样
这个图的区域并不全
还有(调用栈),(任务队列)等区域

stack栈 和 Heap堆
数据区分stack栈 和 Heap堆
stack,每个数据按顺序存放
Heap,每个数据随机存放

一个对象是如何存储的

变量名,存放在不知道叫啥区
对象,存放在Heap区,对象里有新生成的对象,不能直接存,要在新的空间进行存储,
然后存放地址在对象上
生成的地址,存放在stack区

规律

数据分两种,对象和非对象
函数,数组是对象,数字,字符串,布尔是非对象
非对象都存在stack,对象都存在Heap
= 号,总是会把右面的东西复制到左边(不存在传值或传址)

示例

var person={name:"frank"}
var person2=person
person2.name="ryan"
console.log(person.name)      
"ryan"

JS在写代码前,内存是啥样的

JS需要window,浏览器提供window
JS需要console,浏览器提供console,并挂在window上
JS需要document,浏览器提供document,并挂在window上
JS需要对象,浏览器提供Object,并挂在window上
var person = { }   等价于  var person = new Object()
JS需要数组(一种特殊的对象),浏览器提供Array,并挂在window上
var = [1,2,3]      等价于    var a = new Array(1,2,3)
JS需要函数(一种特殊的对象),浏览器提供Function,并挂在window上
function f(){}     等价于   var f = new Function()

把window用内存图画出来

所有东西都挂在window上,所以window至少是一个变量,环境。 存放在不知道叫啥区

更简单的画法

关于window的细节

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

同理
Console 和 console对象,不是同一个东西
Object 和 object函数对象,不是同一个东西
前者是内存地址,后者是数据

什么时候属性有prototype属性
一般来说,首字母是大写的,就有prototype

console.dir(window.Object)
打出它的结构

原型链

问题

var obj ={}
obj.toString()

这个代码为什么不报错?为什么可以运行
obj 有一个隐藏属性,存储了Object.prototype对象地址
obj.toString(),发现obj上没有 toString
就去隐藏属性对应的对象里找
于是就找到了Object.prototype.toString

如果声明一个空对象,它有个隐藏属性,指向prototype
如果定义一个数组,它也有个隐藏属性,指向prototype
JS在创建之初,就在内存中存了 Objct,Array 的prototype属性,用来对应隐藏属性的

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

原型让你无需重复声明共有属性,省代码,省内存,省事

隐藏属性

每一个对象都有一个隐藏属性,指向原型(对象)的共有属性

隐藏属性的名字:_ _ proto _ _

prototype  和  _ _ proto _ _  区别

都存着原型的地址
prototype     挂在函数上
_ _proto_ _   挂在新生的对象上

详细资料点击:JavaScript 继承与原型链