一介绍
随着 js 不断深入, 你可能会慢慢的好奇, 用了这么久的 js, 却不知道这 js 在浏览器怎么被执行的, 很尴尬, 哈哈所以, 我查阅很多资料来总结 JS 的执行过程, 也分享出来, 和大家一起学习
本篇主要讲单线程的 JS
涉及的名词: JS 引擎, 单线程, 执行栈, 执行上下文(execution context)
二 JS 引擎
JS 引擎是浏览器的重要组成部分, 主要用于读取并执行 js 就是这家伙执行 js 的, 但它不止于执行 js
各大浏览器的 JS 引擎:
浏览器 | Js 引擎 |
---|---|
Chrome | V8 |
Firefox | SpiderMonkey |
IE | Chakra(查克拉) |
Safari | Nitro/JavaScript Core |
Opera | Carakan |
虽然每个浏览器的 JS 引擎都不同, 但他们执行 js 机制大致相同
三 JS 执行是单线程
单线程是指 Js 引擎执行 Js 时只分了一个线程给他执行, 也就是执行 js 时是单线程的
先通俗的了解线程
有人可能会疑惑, 线程是什么?
我直接举个直观点例子吧, 你打开一个浏览器(应用程序), 那浏览器就是一个进程打开浏览器后要做很多事情(各种分工): 发送请求, 接受请求, 渲染页面, 执行 js 等等这些就是一个个线程
我这里只是简单的说一下, 具体的大家可以找计算机操作系统资料深入学习
Js 为什么是单线程
有可能有疑惑, 为什么 js 执行要单线程, 如果多线程不是可以执行得快一点吗?
这个要回到 Js 历史了, 布兰登. 艾奇 (Brendan Eich) 老哥用 10 天创造 js 当时 js 用来干嘛, 简单的浏览器交互, 验证, 操作一下 dom 是吧那把它设计成那么复杂干什么, 而且如果多线程的话, 操作 dom 会出现麻烦的事情, 假设一个线程读取 DOM 节点数据的同时, 另一个线程把那个 DOM 节点删了, 呵呵所以 js 一个线程就够了, 也就是一步一步顺序运行下来
证明一下 js 执行是单线程
单线程只能一个个排着队执行, 所以执行以下代码会导致阻塞(有个 while 死循环), 不会弹出 hello
- while (1) {}
- alert('hello');
四执行栈
为了实现 js 执行时的单线程, js 引擎维护着一个执行栈(先进后出)
来个例子: 运行这段代码时执行栈是怎么做的
- // 运行代码
- sayHello();
- function sayHello() {
- var message = getMessage();
- console.log(message);
- }
- function getMessage() {
- return 'hello';
- }
执行栈代码模拟
- // 执行栈
- var exeStack = [];
- // 先压如全局执行环境
- exeStack.push('globalContext');
- // 遇到执行 sayHello 函数, ok, 压进去
- exeStack.push('sayHello');
- // 执行 sayHello 函数发现, 还有个 getMessage 函数, ok, 压进栈
- exeStack.push('getMessage');
- // 执行完了 getMessage 函数, 弹栈
- exeStack.pop();
- // 继续执行 sayHello 函数, 又发现有 console.log 这个家伙, ok, 你进栈
- exeStack.push('console.log');
- // 执行了 console 后, 输出 hello,console 弹栈
- exeStack.pop();
- // 这时 sayHello 执行完, 弹栈
- exeStack.pop();
- // 最后整个代码执行完, 全局环境弹栈
- exeStack.pop();
执行栈图示:
这里主要是 js 在执行时的一个总体过程, 但是你们可能会疑惑, 压进栈里面的一块块 (抽象) 东西到底包含的是什么?
我可以告诉你们是, 执行上下文, global 是指全局的的执行上下文, 其他的是函数执行上下文, 那到底这些上下文包含什么, 我会在下一篇写
五小结
这篇主要是将 js 单线程是什么, 并且怎么实现单线程的有个总体 js 执行过程的印象, 接下来会讲解更多里面的东西就像是挖掘机一样, 深挖下去
如果你觉得困难, 那也许就是在进步
来源: https://juejin.im/post/5a7bf0acf265da4e9449a4b1