重读MDN查漏补缺~~
文中的「TODO」字样,意在提醒我自己这里还有知识点,以后可以用作写博客的主题(或者续写、扩展)
什么是JavaScript
老生常谈,学一个东西就要知道他是什么。
JS是什么呢?一门语言,一门脚本语言。
JavaScript 可以做什么?
他让静态的页面动起来,这个 “动” 并不仅仅是像动画一样动起来的 “动”,而是指里面的数据动起来、事件可以被用户出发后发生响应的动起来。
JS有一些基础的 “能力”,比如说点击事件之后和用户发生交互行为、通过JS操作DOM树中的一个个节点、通过变量存储页面中的一些值等等。
除此之外,还有个东西能让我们的代码变得能做更多的事(MDN原话:就像赋予了超能力。
这是什么东西呢?
API
应用程序接口( Application Programming Interfaces(API))
API 是什么?为什么会有这么强大的 “魔力”?
API 是一套已经建立好的代码组件,可以让开发者轻松实现原本很难或者根本没办法实现的程序。
就好比木材家具,我们用现成的成品,总好过自己用木材去拼来的快来的轻松吧。
我一直以来的理解是,它内部实现了很多方法,我们只要调用这些方法就可以。
API文档
那API文档又是什么呢? 那就是介绍这些内置方法「怎么使用的、需要传什么参数、返回值是什么」的一个文档
add(a, b){
return a+b
}
add(1, 2) // 3
就比如上面这段,我们执行add(1,2)就是用一个接口,API就是通过一些特殊方法,把上面这段add(a, b){ return a+b }在我们的视野中隐藏了,让他这段 对两数相加的实现过程隐藏,不可见,我们只知道调用add(a, b)就可以计算两数之和
API分两类,一种是浏览器API,一种是第三方API。
浏览器API
浏览器 API 内建于 web 浏览器中,它们可以将数据从周边计算机环境中筛选出来,还可以做实用的复杂工作。
例如Geolocation API提供了一些简单的JavaScript结构以获得位置数据,因此您可以在Google地图上标示您的位置。
(当然,我自己的话我也没看过这个获取位置数据的API怎么用,之所以搜到上面这段是因为我不知道所谓计算机环境是什么,又能从计算机环境获取到什么数据。
(现在看来的话,可以获取到位置信息,草草瞥了一眼搜到的其他结果,可能计算机本地内存的一些信息也能够获取到。这话真假不论,好歹对这个计算机环境有个初印象了。
先说浏览器API,它被内置在浏览器里面,说到底就是浏览器可以调用这些API里面被写好的方法来完成一些操作:
比如说拿去计算机环境中的一些数据,
比如做一些其他的复杂工作,例如:
文档对象模型 API(DOM(Document Object Model)API),我们熟知的getElementById就是其中一个,对DOM元素增删改查,也可以添加属性、操控样式。地理位置 API(Geolocation API)获取地理位置的API,各种地图可以获取我们的位置然后标注在地图上画布(Canvas)和WebGLAPI,可以创建生动的 2D 或者 3D图像- 诸如
HTMLMediaElement和WebRTC等 影音类 API,可以让我们操作多媒体完成我们想要的效果,比如「网页中播放音乐播放视频」、「用摄像头获取图像」等等
好吧说实话,这里面很多API我也没有用过,但是我们应该有个印象,那就是各种API再不同的方向产生自己的作用,他们很强大,可以把他们理解为浏览器支持的一些内置方法。
第三方API
第三方API没有嵌入在浏览器,我们需要从第三方去获取。
第三方 API 并没有默认嵌入浏览器中,一般要从网上取得它们的代码和信息。比如:
- Twitter API、新浪微博 API 可以在网站上展示最新推文之类。
- 谷歌地图 API、高德地图 API 可以在网站嵌入定制的地图等等。
第三方API,想来应该是那些软件提供的可以让其他软件引用的一些接口。
JavaScript库,体量相对比较小,比如jQuery,仅仅就是工具啊工具。成不了一个完整的程序。
JavaScript框架,比如Vue。
- 第三方API — 置于第三方普通的结构程序(例如Twitter,Facebook),使您可以在自己的Web页面中使用那些平台的某些功能(例如在您的Web页面显示最新的Tweets)。
- JavaScript库 — 通常是包含具有特定功能的一个或多个JavaScript文件,把这些文件关联到您的Web页以快速或授权编写常见的功能。例如包含jQuery和Mootools
- JavaScript框架 — 从库开始的下一步,JavaScript框架视图把HTML、CSS、JavaScript和其他安装的技术打包在一起,然后用来从头编写一个完整的Web应用。
三者区别的参考:Web API。(可以看看这个链接,goodgood~TODO
清晰又明了啊兄弟们 👍 。
JS 在页面做了什么?
浏览器读取网页的时候,代码(HTML、CSS、JavaScript)在一个运行环境(一个浏览器的标签页)里面得到执行。
就像一个工厂,把原材料(代码)加工成一个成品(网页)。
JS代码应该在 HTML、CSS这个集合组装成一个网页之后,再(由浏览器的 JavaScript 引擎)执行。因为JS最普遍的操作就是操作DOM元素更新页面,如果JS运行的时候,DOM元素还没有生成(HTML、CSS还没有加载),那就会报错。
所谓浏览器安全
每个浏览器标签页都是一个运行代码的独立容器,这些容器我们称为运行环境。
普通来说,不同的运行环境之间不会相互影响,这个标签页的代码影响不了另一个标签页(或者另一个网站)的代码。这样就能保证不同标签页之间不会轻易获取信息之类的了,安全。
用安全的方式在不同网站之间进行代码或者数据的传送的方法是存在的,但是目前可以先不用知道。(TODO
JavaScript 运行次序
自上而下执行,引用变量之前应当确保变量已经被定义(即:变量存在)。
解释代码 ? 编译代码 ?
解释( interpret )代码:代码自上而下,按照顺序运行,比如JS,实时返回结果。在浏览器执行之前,不需要将代码转化为别的形式,代码直接用文本形式(text form)被接收和处理
编译( compile )代码:相比解释代码,编译代码需要被转化(编译)成其他的形式才能运行。
比如C/C++先被编译成汇编语言,才能由计算机运行。
程序转译成汇编语言后又变成二进制的格式被运行。(应该是,TODO
JavaScript是轻量级解释型语言,虽然是解释型语言,但它却不是以代码自身的文本格式运行,几乎所有的JavaScript转换器都用了一种叫做即时编译(just-in-time compiling)的技术,当JS源代码被执行的时候,代码就会被编译成二进制的格式,这会让他的运行速度变快。
总的来说,虽然他会被编译成二进制,但是根本上来说他还是解释型语言,因为它在代码运行的过程中编译,而不是在代码运行之前编译。
服务端代码 ? 客户端代码 ?
服务器端(server-side) 代码运行在服务器
客户端(client-side) 代码运行在用户这里
一般js是客户端代码,但现在有了Node.js,所以它也可以成为服务端代码。
动态代码 ? 静态代码 ?
什么是动态代码呢?
是指通过按需生成新内容来更新 web 页面 / 应用,使得不同环境下显示不同内容。
服务端代码的动态在于从数据库请求信息之后生成新内容,js的动态在于请求后端接口,获取数据,渲染页面。
两者虽然有不同,但也有相似。
没有动态更新内容的网页叫做“ 静态 ”页面,所显示的内容不会改变。
怎么在页面添加 JS ?
<script>标签,可以用来从外部引入,也可以用来在内部写js代码。
当引用了外部的js文件的时候,在同一个标签内部写的代码将不会起作用(被忽略了)。
<script src="script.js" > // src引外部js文件
// 在标签内编写 JavaScript 代码
</script>
脚本调用策略
副标题:延迟执行JS
我们之前不是说,应该在HTML、CSS加载结束之后加载JS代码。那怎么才能保证这种顺序呢?
load 事件
当
整个页面以及所有的依赖项资源( 比如样式表、图品 )都完成加载的时候,就会触发 load 事件
一般就是下面这么用,直接监听window的load事件
window.addEventListener('load', (event) => {
console.log('整个页面及所有依赖资源如样式表和图片都已完成加载');
});
window.onload
本质上是 load 事件的另一种写法。
window.onload = (event) => {
console.log('网页被完全加载');
};
DOMContentLoaded 事件
和 load 事件不同, DOMContentLoaded事件:
只需要HTML文档被完全加载和解析完成之后就会触发,不需要等样式表、图像、子框架完全加载。
换句话说DOMContentLoaded只需要等DOM加载完成就触发,无需等待依赖资源的加载。
<script>
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM 完全加载并解析");
});
</script>
优化
如果您希望 DOM 在用户请求页面后尽可能快地解析,你可以做的一些事情是把你的 JavaScript 异步化 以及 优化样式表的加载, 由于被并行加载而减慢页面加载,从主 html 文档“窃取”流量。(TODO
把标签放在文档最后
这也是个法子,但这些,说实话,都有一个弊端,都是要等到html DOM 加载完毕之后才会开始加载/解析脚本。 对于有大量js代码的网站来说,这样就很耗费性能。
async 和 defer
上面几种都适用于在内部 <script> 标签里面用的方法,当我们从外部引用 js文件 的时候,我们可以用async 或者 defer属性。
这也是解决前面几个方法的弊端的一个方案。
简单说,async和defer都是可以不阻塞页面DOM的正常渲染的,但两者略有区别。
async:js文件什么时候下载下来什么时候执行,不管这个HTML DOM有没有解析完毕。
而且如果有好几个外部链接的话,像下面这样,那他们几个文件的顺序是没办法保证的,谁先下载完谁执行。
<script async src="js/vendor/jquery.js"></script>
<script async src="js/script2.js"></script>
<script async src="js/script3.js"></script>
defer:这个的话,就可以保证「不管我有没有下载完,我都会在HTML DOM解析完毕之后解析」,并且如果同样有好几个外部脚本「我保证按照代码中脚本的顺序下载并执行这些脚本」
注释
// 单行注释
/*
多行注释
*/
变量 - 存储所需信息
跳一跳跳一跳,跳到变量来看一看。
什么是变量
变量存储我们所需要的信息,这个信息可以是数值、字符串或者对象等等。
变量不是信息本身,他是存储信息的容器。
打个比方,变量就是一个装东西的箱子。
声明变量
使用「箱子」之前我们需要拥有一个「箱子」,怎么才能拥有一个「箱子」呢?
怎么才能拥有一个变量呢?——创建它。
或者我们也可以说声明变量:
var myname;
let myage;
就像上面,我们可以用var声明一个变量,也可以用 let声明一个变量,我们暂时不对这两者做出区分,后面再说~
初始化变量
什么是初始化变量?就好比我创建一个箱子的时候顺手往里面塞了东西。
var myName = 'zzx';
let myage = 3;
var ? let ?
为什么会有两个关键字用来声明变量?一个不够用吗?
简单说:
var是es6之前的产物,只能用来声明全局作用域和函数作用域。
而let是是es6的产物,声明块级作用域。
var会有变量提升。
let有暂时性死区。
变量类型
7种基本类型:string,number,bigint,boolean,null,undefined,symbol (ECMAScript 2016新增)。
1个对象:Object
这段可以看看,关于对象的数据属性 对象(TODO