js 入门
推荐结合图书Javascript 高级程序设计-第三版学习
什么是 javascript?
JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。
特点:
- 在浏览器(主)运行: 解释型语言,运行环境需要解析器,移植性强(node)
- 弱类型: 数字 10 字符串 "10"
- 单线程: 避免多线程语言的类似死锁情况,其实也可以创建多个线程,但是核心内容(页面渲染)依然是主线程承担
- 异步: 主要的执行方式
web 技术 3 大板块:
HTML
是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。CSS
是一种样式规则语言,可将样式应用于 HTML 内容, 例如设置背景颜色和字体,在多个列中布局内容。JavaScript
是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。(好吧,虽然它不是万能的,但可以通过简短的代码来实现神奇的功能。)
如何引入 javascript?
1. 页内的引入
<script type="text/javascript">
alert("hello world!");
</script>
2. 页外引入
<script type="text/javascript" src="js/test.js"></script>
3. 行内的引入
<div onclick="alert('你点到我了!')">点击这里!</div>
js 单线程机制
参考文章: https://www.jianshu.com/p/e06e86ef2595
1. 基础知识
- js 作为浏览器脚本语言,它的主要用途是与用户互动,以及操作 DOM,因此 js 是单线程,也避免了同时操作同一个 DOM 的矛盾问题;
- 为了利用多核 CPU 的计算能力,H5 的 Web Worker 实现的“多线程”实际上指的是“多子线程”,完全受控于主线程,且不允许操作 DOM;
- js 引擎存在 monitoring process 进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去 Event Queue 那里检查是否有等待被调用的函数。这个过程是循环不断的,所以整个的这种运行机制又称为 Event Loop(事件循环)
- 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack);
- 如果在微任务执行期间微任务队列加入了新的微任务,会将新的微任务加入队列尾部,之后也会被执行;
2. js 中的异步操作
- setTimeOut
- setInterval
- ajax
- promise.then
- I/O
3. 同步任务 or 异步任务
- 同步任务(synchronous):在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
- 异步任务(asynchronous):不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
4. 宏任务 or 微任务
这里需要注意的是 new Promise 是会进入到主线程中立刻执行,而 promise.then 则属于微任务
宏任务(macro-task): 整体代码 script、
setTimeOut
、setInterval
微任务(mincro-task):
process.nextTick
、promise.then
!> 注意: promise
是同步,promise.then
才是异步, process.nextTick
的优先级高于 promise.then
5. Event Loop 事件循环
- 整体的 script(作为第一个宏任务)开始执行的时候,会把所有代码分为两部分:“同步任务”、“异步任务”;
- 同步任务会直接进入主线程依次执行;
- 异步任务会再分为宏任务和微任务;
- 宏任务进入到 Event Table 中,并在里面注册回调函数,每当指定的事件完成时,Event Table 会将这个函数移到 Event Queue 中;
- 微任务也会进入到另一个 Event Table 中,并在里面注册回调函数,每当指定的事件完成时,Event Table 会将这个函数移到 Event Queue 中;
- 当主线程内的任务执行完毕,主线程为空时,会检查微任务的 Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务;
- 上述过程会不断重复,这就是 Event Loop 事件循环;
console.log("1");
setTimeout(function () {
console.log("2");
process.nextTick(function () {
console.log("3");
});
new Promise(function (resolve) {
console.log("4");
resolve();
}).then(function () {
console.log("5");
});
});
process.nextTick(function () {
console.log("6");
});
new Promise(function (resolve) {
console.log("7");
resolve();
}).then(function () {
console.log("8");
});
setTimeout(function () {
console.log("9");
process.nextTick(function () {
console.log("10");
});
new Promise(function (resolve) {
console.log("11");
resolve();
}).then(function () {
console.log("12");
});
});
// 结果
// 1,7,6,8,2,4,3,5,9,11,10,12