《现代 JavaScript 教程 》内容汇总——JavaScript基础知识
入职以后由于公司技术栈更多的使用JS,所以决定给一边学习JS一边写一些心得体会。本文只会着重讲一些学习过程中发现的JavaScript相比于其它语言具有的特性或者优点和区别。
现代JavaScript教程的链接是现代 JavaScript 教程,在学习过程中我也逐渐发现了JS的精妙之处。只能说一门流行的语言不管先天上带着多少缺陷,带着这些历史包袱前行究竟有多费力。都不能掩盖语言本身演化过程中所创造出的精妙思想。
JavaScript的特点
JavaScript
最开始是专门为浏览器设计的一门语言,但是现在也被用于很多其他的环境。譬如Node.js
- JavaScript 与 HTML/CSS 完全集成的,是使用最广泛的浏览器语言。
- 有很多其他的语言可以被"编译"成 JavaScript,这些语言还提供了更多的功能。比如常用的添加了"严格的数据类型"的
TypeScript
,它被广泛应用于复杂系统开发
"script"标签
<script>
标签中包裹了 JavaScript 代码,当浏览器遇到<script>
标签,代码会自动运行。- 脚本文件可以通过
src
特性(attribute)添加到 HTML 文件中,可以提供从网站根目录开始的绝对路径,当前目录的相对路径以及完整的URL地址。 - 当引入模块时,由于模块支持特殊的关键字和功能,因此我们必须通过使用
<script type="module">
特性(attribute)来告诉浏览器(只通过HTTP(s)工作,在本地文件不行。)
语句
- 通常情况下换行意味着分号,但这不是绝对的,所以不建议省略分号。
"use strict"
- 确保"use strict"位于最顶部,否则严格模式可能无法开启。(包括脚本文件或者函数体)
- 无法取消严格模式。
- 现代 JavaScript 支持 "classes" 和 "modules" —— 高级语言结构(本教程后续章节会讲到),它们会自动启用
use strict
。因此,如果我们使用它们,则无需添加"use strict"
指令。
变量
- 使用关键字
let
而非var
- 变量名称必须仅包含字母,数字,符号
$
和_
,首字符必须非数字。 - 使用大写字母和下划线来命名常量。
数据类型
- JavaScript共有七种原始类型,分别是
string
,number
,bigint
,boolean
,symbol
,null
和undefined
,和一个特殊类型object
。
Number
- 特殊数值:
Infinity
(无穷大∞)、-Infinity
和NaN
(计算错误,且为粘性的任何对NaN的进一步操作都会返回NaN)。
BigInt
- 可以通过将
n
附加到整数字段的末尾,或者调用BigInt
函数,该函数从字符串、数字等中生成 bigint。 - 不可以把 bigint 和常规数字类型混合使用,应该显式转换。
- 比较运算符可以用于bigint和number类型数字的比较,但由于bigint和number属于不同类型,可能在 == 比较时相等 但在===(严格比较)时不相等。
String
- 必须被括在括号内,可使用双引号"",单引号'',反引号``,反引号是功能扩展引号,允许我们将变量或表达式括在${…}中来嵌入字符串
Boolean
- 仅包含
true
'和false
两个值。
null
- 仅代表一个"无"、"空"、和值未知的特殊值。
undefined
- 代表一个变量已经被声明但未被赋值,所以不建议使用undefined来为变量赋值
object
- object类型相比上述"原始类型"(值只包含一个单独的内容),用于储存数据集合和更复杂的实体。
symbol
交互:alert、prompt和confirm
关于这三个函数其实可以讲的不多,但有一点很重要。
这些方法都是模态的:它们暂停脚本的运行,且不允许用户与该页面的其他部分互动,直到窗口被解除。
在这里推荐一篇文章讨论了为什么现代网页很少看到confirm模态框
Never Use a Warning When you Mean Undo - A List Apart
类型转换
字符串转换
转换发生在输出内容的时候,也可以通过 String(value)
进行显式转换。原始类型值的 string 类型转换通常是很明显的。
数字型转换
undefined
=> NaN
null
=> 0
true
/ false
=> 1
/ 0
string
=> "按原样读取"字符串,两端的空白会被忽略。空字符串变成 0
。转换出错则输出 NaN
。
布尔型转换
0
, null
, undefined
, NaN
, ""
=> false
其他值 => true
由于原始类型只提供单个值,但JavaScript 允许访问字符串,数字,布尔值和 symbol 的方法和属性。所以提供提供了额外功能的特殊"对象包装器"
String、Number、Boolean、Symbol
基础运算符
数字转换,一元运算符+
一元运算符加号,或者说,加号 +
应用于单个值,对数字没有任何作用。但是如果运算元不是数字,加号 +
则会将其转化为数字。
逗号运算符
逗号运算符 ,
是最少见最不常使用的运算符之一。有时候它会被用来写更简短的代码,因此为了能够理解代码,我们需要了解它。
逗号运算符能让我们处理多个语句,使用 ,
将它们分开。每个语句都运行了,但是只有最后的语句的结果会被返回。
var x = [0,1,2,3,4,5,6,7,8,9]
var a = [x, x, x, x, x];
for (var i = 0, j = 9; i <= j; i++, j--)
console.log('a[' + i + '][' + j + ']= ' + a[i][j]);
值的比较
- 比较运算符始终返回布尔值。
- 字符串的比较,会按照"词典"顺序逐字符地比较大小。
- 当对不同类型的值进行比较时,它们会先被转化为数字(不包括严格相等检查)再进行比较。
- 在非严格相等
==
下,null
和undefined
相等且各自不等于任何其他的值。 - 在使用
>
或<
进行比较时,需要注意变量可能为null/undefined
的情况。比较好的方法是单独检查变量是否等于null/undefined
。
空值合并运算符'??'
在本小节中我们把既非null
亦非undefined
的表达式称为"已定义的defined"
举例:a??b
如果a
是已定义的,则结果是a
;
如果a
不是已定义的,则结果是b
由此我们发现??与||类似,在??诞生前我们使用||,但与||相比??具有以下特点:
||
返回第一个真值,而真值包括除了(fasle
、0
、""
、以及null
和undefined
),在实际环境中我们可能只想要过滤null
和undefined
除此之外??还具有两个特点:
- 优先级低,仅比=和?高,因此使用时请加上括号
- 为了避免
||
切换到??
时出错,??
不允许和&&
、||
一起使用。(不过可以通过增加括号来避开)
"switch"语句严格相等
函数表达式和函数声明
函数声明: function sayHi() { alert( "Hello" ); }
函数表达式: let sayHi = function() { alert( "Hello" ); };
由于在JavaScript中函数也是一种特殊的值,所以上述两段代码都代表着将函数存放到变量sayHi中,函数表达式需要在末尾加上分号代表语句结束。
- 函数表达式是在代码执行到达时被创建,并且仅从那一刻起可用;
- 但函数声明在被定义之前,它就可以被调用,函数声明具有块作用域。
箭头函数
箭头函数的形式类似: let func = (arg1, arg2, ...argN) => expression
这里创建了一个函数 func
,它接受参数 arg1..argN
,然后使用参数对右侧的 expression
求值并返回其结果。
举几个例子:
let sum = (a, b) => a + b;
创建一个函数sum,传入参数a和b,返回a + b的计算结果。let double = n => n * 2;
当只有一个参数时可以省略括号,传入参数n,返回n * 2的结果。let sayHi = () => alert("Hello!");
如果没有参数时则应该保留括号。let welcome = (age < 18) ? () => alert('Hello') : () => alert("Greetings!");
箭头函数可以像函数表达式一样使用。let sum = (a, b) => { let result = a + b; return result; };
如果是多行的表达式或者语句需要使用花括号括起来,并添加返回语句return。- 箭头函数没有"this",会从外部中获取"this",所以也没有构造函数,因此不能使用new;没有arguments;没有super
Polyfill
Babel
Babel 是一个转换编译器,它能将 ES6 转换成可以在浏览器中运行的代码。Babel 可以处理 ES6 的所有新语法,并且内置了 React JSX 扩展及 Flow 类型注解支持。
Polyfill
Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。