图解JS内存与原型
1.js引擎介绍
- Chrome 用的是V8引擎,由C++语言编写
- 网景用的是 SpiderMonkey,后被Firefox使用,C++
- Safari 用的是JavaScriptCore
- IE用的是 Chakra (JScript9)
- Edge用的是 Chakra (JavaScript)
- Node.js 用的是V8引擎
主要功能
- 编译:把JS代码翻译为机器能执行的字节码或机器码
- 优化:改写代码,使其更高效
- 执行:执行上面的字节码或者机器码
- 垃圾回收:把JS用完的内存回收,方便之后再次使用
2.全局对象window
window下的对象
- document
- setTimeout
- setInterval
- navigator
- screen
- 等等
3.内存世界
上图描述了我们计算机中的内存的分布,左边OS为操作系统所占用的内存,当我们打开chrome浏览器时,会开启一个主进程,然后会开启其他的子进程,当我们每打开一个页面的时候就会开启一个新的进程,上图右侧部分为模拟一个页面的进程的内存使用情况,实际上还有调用栈和任务队列等内存区。
栈内存与堆内存
红色区域分为 Stack栈和 Heap堆
Stack区特点:每个数据顺序存放 一般用来存放简单数据类型,数字,字符串,布尔
Heap区特点:每个数据随机存放 一般用来存放复杂数据类型,对象
下面简单模拟这段代码的内存情况
var a = 1;
var b = 1;
var obj = {
name:"frank",
child:{
gender:"男"
}
}
var obj2 = obj;
模拟window对象在内存中的情况
注意
- window变量和window对象是两个东西
- window变量是一个容器,存放window对象的地址
- window对象是Heap里的一坨数据
4.JavaScript原型对象,原型链
请看下面这样一段代码
var a = {}
a.toString(); // "[object Object]"
为什么空对象可以运行toString方法呢
解释
- obj有一个隐藏属性 proto
- 隐藏属性存储了Object.prototype对象的地址
- 就去隐藏属性对应的对象里面找
- 于是就找到了Object.prototype
在看这段代码在JS内存世界的表示
var obj = {};
var arr = [];
学过其他比后端语言比如如C++语言的同学应该都知道构造函数,其实window下的Array,Object,Function这些也是构造函数
var a = new Array(); // 构造函数创建法
相当于
var a = [];
构造函数的prototype其实就是用来存储构造出来的对象所共有的属性或方法,这样一来就会节省代码和内存
而由构造函数所创建的对象又有了proto 这个属性值 这个属性值保存的就是该对象所属的构造函数的原型对象(prototype)的地址,这样一来,该对象就可以使用原型对象上面的所有属性和方法
prototype与proto的区别?
- 都存着原型的地址
- 只不过prototype挂在函数上
- proto挂在每个新生成的对象上