wangjie-fourth 的个人博客

may be just need work hard

目录
JS在游览器的内存分布
/      

JS在游览器的内存分布

一、前言

1、游览器请求一个地址的过程

当游览器在请求某个地址后,会从服务器下载HTML、解析HTML;随后,下载CSS、解析CSS、渲染界面,下载JS、解析并执行JS。这时候,大致分为以下部分:

  • 渲染引擎渲染界面,主要是HTMLCSS代码;
  • JS引擎执行JS代码;
  • 游览器本地存储;

所以,当请求某个页面后,通常会产生俩个线程。

  • 一个用来渲染界面,一个用来执行JS代码;
  • JS引擎不能直接渲染界面,它是通过线程之间通信告诉渲染引擎去修改;这要是为什么DOM操作慢得原因,因为它涉及到了线程之间得操作;

2、JS引擎

JS引擎是用来解析、运行JS代码,你可以理解成JVMJS引擎主要的功能有:

  • 编译:把JS代码翻译为机器码;
  • 优化:改写代码,始其更高效;
  • 执行:执行上面的字节码或者机器码;
  • 垃圾回收:把JS用完的内存回收;

常见的JS引擎有:

  • ChromeNode.js用的V8引擎,是用C++编写的;
  • Firefox用的SpiderMonkey,也是用C++编写的;
  • IE用的Chakra

二、游览器中的JavaScript

游览器在解析、执行JS代码之前,会事先准备好相关对象。比如说:windowdocumentsetTimeout等等,需要注意的是这些不是JS的功能,而是游览器的功能;然后JS会提供能执行JS代码的运行环境。

1、游览器提供的API

(1)window
表示游览器
(2)console
表示控制台

console.dir():显示一个对象的结构

(3)document
(4)Object
表示对象

var person = {} 等价于 var person = new Object()

(5)Array
表示数组(一种特殊的对象)

var a = [1,2,3] 等价于 var a = new Array(1,2,3)

(6)Function
表示函数(一种特殊的对象)

function f()等价于var f = new Function()

为什么要挂在window上?
因为方便,挂在window上的东西可以在任何地方直接使用

2、一个Tab页所对应内存

image.png

(1)一般首字母大写的对象,会有prototype属性。比如:ObjectArray

(2)window变量和window对象是俩个东西
window变量是放在存放变量名的区域,而window对象是在Heap中,window变量存放的是window对象的地址。就跟java的变量名和对象。
这是游览器默认做好的工作。它在执行JavaScript代码之前,就创建好window变量,并用window变量名来存放这个window变量的地址。之所以用window变量名就是为了好记。同理还有consoleObject等等。

(3)JQuery的别名$
JQuery也是放在window对象里。为了方便使用JQuery,就用$来代替。其实就相当于执行了var $ = window.jQuery
image.png

3、原型链:prototype

背景

为了避免重复声明共有属性,JS引入原型的概念,并通过原型链,让多个对象共享相同的共有属性。这不仅节省代码行数,还节省内存。原型:XXX.prototype存储了XXX对象的共同属性,这就是原型。

相关问题

(1)空对象的toString从哪里来的?

var obj = {};
obj.toString();

这里仅仅声明一个空对象,它的toString属性从哪里来的?

  • 每一个对象都有一个隐藏属性__proto__,普通对象的隐藏属性指向的是Objectprototype
  • obj.toString()会先在objtoString,没有就去隐藏属性找;
  • 所以obj.toString()就是window.Object.prototype.toString()
    image.png

(3)空数组的push从哪里来

  • 这个空数组对象也有隐藏属性__proto__,数组对象的隐藏属性指向的是Arrayprototype
  • a.push()会先在a中找;再到Arrayprototype找;最后到Objectprototype找;
  • 所以a.push()就是window.Array.prototype.push
    image.png

(4)当我们修改一个对象的toString(),会影响后面新建对象的toString()方法吗?
不会。上面那个只针对读操作,如果是写操作,是另一种流程。
在写的时候,只有在一层才能写成功;超过一层就不会写进去,只会写在第一层中。
image.png
详细图如下:
image.png

(5)prototype__proto_的区别
他们都保存这原型的地址。
只不过prototype挂在函数上,而__proto_挂在每个新生成的对象上


参考资料:

评论