本文主要参考[1][2][3][4]

JavaScript

JavaScript可以分为三部分[5]

注:这里暂时没找其他的理论依据,但是道理大概是这么回事

  • ECMAScript:核心,描述了Js语法及各种标准,目前通用的有ES5,更新的是ES6
  • DOM(文档对象类型):HTML和XML的API。用DOM API可以轻松地删除、添加、替换节点
  • BOM(浏览器对象模型):对浏览器窗口进行访问和操作(不同浏览器有自己的实现,没有统一标准)

应用程序接口(Application Programming InterfacesAPI)) [6]

API 通常分为浏览器API和第三方API

浏览器API包括DOM API、地理位置API、画布和web GL API,以及 HTMLMediaElementWebRTC影音类 API

JavaScript 在页面上做了什么

在 HTML 和 CSS 集合组装成一个网页后,浏览器的 JavaScript 引擎将执行 JavaScript 代码。

JavaScript 最普遍的用处是通过 DOM API(见上文)动态修改 HTML 和 CSS 来更新用户界面 (user interface)。

每个浏览器标签页就是其自身用来运行代码的独立容器(运行环境)

解释型和编译型

在解释型语言中,代码自上而下运行,且实时返回运行结果。

JavaScript 是轻量级解释型语言。浏览器接受到JavaScript代码,并以代码自身的文本格式运行它。技术上,几乎所有 JavaScript 转换器都运用了一种叫做 即时编译 (JIT,Just-In-Time compiling)的技术;当 JavaScript 源代码被执行时,它会被编译成 二进制的格式 ,使代码运行速度更快。尽管如此,JavaScript 仍然是一门解释型语言,因为编译过程发生在代码运行中,而非之前。

添加Js的方法

内部JavaScript

1
2
3
4
5
<script>

// 在此编写 JavaScript 代码

</script>

外部JavaScript

1
<script src="script.js" async></script>

脚本调用策略

HTML 元素是按其在页面中出现的次序调用的,如果用 JavaScript 来管理页面上的元素(更精确的说法是使用 文档对象模型 DOM),若 JavaScript 加载于欲操作的 HTML 元素之前,则代码将出错。

如果Js脚本位于文档头处,则会在HTML文档体之前解析,存在隐患。需要用一些结构笔面错误发生。

  1. (旧方法)把脚本元素放在文档体的底端(</body> 标签之前,与之相邻),这样脚本就可以在 HTML 解析完毕后加载了。
  2. 监听浏览器的 “DOMContentLoaded” 事件,即 HTML 文档体加载、解释完毕事件。
1
2
3
document.addEventListener("DOMContentLoaded", function() {
. . .
});
  1. 外部引用添加async “异步”属性
1
<script src="script.js" async></script>
asyncdefer
  • 如果脚本无需等待页面解析,且页面的脚本之间彼此独立,不依赖于本页面的其它任何脚本时,那么应使用 async
  • 如果脚本需要等待页面解析,且依赖于其它脚本,调用这些脚本时应使用 defer,将关联的脚本按所需顺序置于 HTML 中。
1
2
3
4
5
<script defer src="js/vendor/jquery.js"></script>

<script defer src="js/script2.js"></script>

<script defer src="js/script3.js"></script>

声明/变量/常量

09-3种声明变量方式 P9 - 01:19 [3:1]

  • var,可变变量,有函数作用域(就是类比函数的话,可以在第1行调用,但是第10行定义)
  • const不可修改(const定义的其实不是变量,是 常量 )
  • let可修改 用在循环

var可以省略,但如果省略后就是全局变量(即使定义在函数内也是全局变量(准确说是全局对象的属性?))

1
2
3
4
5
6
function fun1() {
oopsGlobal = 5;
}
fun1();

console.log(oopsGlobal); // 5

如果访问没有声明的变量会抛出 引用错误(ReferenceError) [7]

变量

一个 JavaScript 标识符必须以字母、下划线(_)或者美元符号($)开头;后续的字符也可以是数字(0-9)

变量未被赋值-》返回undefined

变量提升

JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码(函数)的头部,这就叫做变量提升(hoisting)。[8]

对于var来说,可以先使用变量稍后再声明变量而不会引发异常。

在 ECMAScript 6 中,let(const)同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量,将抛出引用错误(ReferenceError)。

但是只是没有引发异常,变量不能获取之后被赋予的值,此时调用会显示undefined,而如果与数字进行运算,则会输出NaN(因为是非数值undefined进行运算)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 例子1
*/
console.log(x === undefined); // true
var x = 3;


/**
* 例子2
*/
// will return a value of undefined
var myvar = "my value";

(function() {
console.log(myvar); // undefined
var myvar = "local value"; // 这一行的myvar声明被提升到function的开头,因此此时的myvar是违背赋值的状态
})();

/**
* 例子3
*/
console.log(x-10); //NaN
var x = 10;

对于函数来说,只有函数声明function foo() 会被提升到顶部,而函数表达式var baz = function() 不会被提升。

常量const

常量不可以通过重新赋值改变其值,也不可以在代码运行时重新声明。

但是, 对象属性被赋值为常量是不受保护的,可以修改。(同样,数组也属于对象)[7:1]

1
2
3
4
5
6
7
8
9
10
11
const obj = {
"key1":1,
"key2":2
};

obj.key1 = 10;
console.log(obj); // { key1: 10, key2: 2 }

const arr = [1,2,3];
arr[2] = 20;
console.log(arr); // [ 1, 2, 20 ]

数据类型

JavaScript 中的类型应该包括这些:[9]

确定js的类型

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString方法[9:1]
    • 具体使用 Object.prototype.toString.call(i)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
const i = 100;
const f = 0.3;
const s = "hello world";
const arr = [1,2,3];
const b = false;
const n = null;
const u = undefined;
const o = {
"1":1,
o2 :"2"
};
function fn(){
return 1000;
}

const i0 = Number(100);
const i1 = new Number(100);

// typeof
console.log("---typeof---")
console.log(`${i}:\t ${typeof i}`); // number
console.log(`${i0}:\t ${typeof i0}`); // number
console.log(`${i1}:\t ${typeof i1}`); // object
console.log(`${f}:\t ${typeof f}`); // number
console.log(`${s}:\t ${typeof s}`); // string
console.log(`${arr}:\t ${typeof arr}`); // object
console.log(`${b}:\t ${typeof b}`); // boolean
console.log(`${n}:\t ${typeof n}`); // object
console.log(`${u}:\t ${typeof u}`); // undefined
console.log(`${o}:\t ${typeof o}`); // object
console.log(`${fn}:\t ${typeof fn}`); // function
console.log(`${NaN}:\t ${typeof NaN}`); // number

// instanceof
console.log("---instanceof---")
// console.log(`${i instanceof number}`); number is not defined
console.log(`${i instanceof Number}`); // false
console.log(`${s instanceof String}`); // false
console.log(`${i0 instanceof Number}`); // false
console.log(`${i1 instanceof Number}`); // true
console.log(`${o instanceof Object}`); // true
console.log(`${arr instanceof Array}`); // true
console.log(`${fn instanceof Function}`); // true

// prototype
console.log("---prototype---")
console.log(`${Object.prototype.toString.call(i)}`); // [object Number]
console.log(`${Object.prototype.toString.call(f)}`); // [object Number]
console.log(`${Object.prototype.toString.call(s)}`); // [object String]
console.log(`${Object.prototype.toString.call(arr)}`); // [object Array]
console.log(`${Object.prototype.toString.call(b)}`); // [object Boolean]
console.log(`${Object.prototype.toString.call(n)}`); // [object Null]
console.log(`${Object.prototype.toString.call(u)}`); // [object Undefined]
console.log(`${Object.prototype.toString.call(o)}`); // [object Object]
console.log(`${Object.prototype.toString.call(fn)}`); // [object Function]
console.log(`${Object.prototype.toString.call(NaN)}`); // [object Number]

typeof

instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

1
object instanceof constructor

必须是object

instanceof - JavaScript | MDN (mozilla.org)

prototype

字面量(Literals,字面形式)

字面量是由语法表达式定义的常量;或,通过由一定字词组成的语词表达式定义的常量[10]

null, undefined 和布尔值

null

JavaScript 中的 null 表示一个空值(non-value),必须使用 null 关键字才能访问,,转为数值时为0

1
2
3
4
5
6
7
8
9
function fn(){
console.log('Hello World');
}

fn(); // Hello World
fn(null); // Hello World
console.log(Number(null)+1); // 1
console.log(null+1); // 1
console.log(null+'n'); // nulln

undefined

undefined 是一个“undefined(未定义)”类型的对象,表示一个未初始化的值,也就是还没有被分配的值。转为数值时为NaN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 变量声明了,但没有赋值
var i;
console.log(i); // undefined

// 调用函数时,应该提供的参数没有提供,该参数等于 undefined
function f(x) {
return x;
}
console.log(f()); // undefined

// 对象没有赋值的属性
var o = new Object();
console.log(o.p) // undefined

// 函数没有返回值时,默认返回 undefined
function f() {}
console.log(f()); // undefined

console.log(Number(undefined)); // NaN

布尔值

转换规则是除了下面六个值被转为false,其他值都视为true

  • undefined
  • null
  • false
  • 0
  • NaN
  • ""''(空字符串)

注意,空数组([])和空对象({})对应的布尔值,都是true

数值

JavaScript 采用“遵循 IEEE 754 标准的双精度 64 位格式”(“double-precision 64-bit format IEEE 754 values”)表示数字。——在JavaScript(除了BigInt)当中, 并不存在整数/整型(Integer)[11]

1
2
1 === 1.0 // true
0.1 + 0.2 === 0.3 // false 0.1 + 0.2 = 0.30000000000000004

JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。[12]

  • 第1位:符号位,0表示正数,1表示负数
  • 第2位到第12位(共11位):指数部分 (0到2047)
  • 第13位到第64位(共52位):小数部分(即有效数字)

精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-253到253,都可以精确表示。

简单的法则就是,JavaScript 对15位的十进制数都可以精确处理。

正向溢出与负向溢出

JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。

1
2
Math.pow(2, 1024) // Infinity
Math.pow(2, -1075) // 0

JavaScript 提供Number对象的MAX_VALUEMIN_VALUE属性,返回可以表示的具体的最大值和最小值。

科学计数法/浮点数字面量

1
2
3
4
123e3 // 123000
123e-3 // 0.123
-3.1E+12
.1e-23

浮点数字面值可以有以下的组成部分:

  • 一个十进制整数,可以带正负号(即前缀“+”或“ - ”),
  • 小数点(“.”),
  • 小数部分(由一串十进制数表示),
  • 指数部分。
1
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
1
2
3
4
3.14
-.2345789 // -0.23456789
-3.12e+12 // -3.12*10^12
.1e-23 // 0.1*10^(-23)=10^(-24)=1e-24

整数进制字面量

  • 十进制:没有前导0的数值。
  • 八进制:有前缀0o0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
  • 十六进制:有前缀0x0X的数值。
  • 二进制:有前缀0b0B的数值。

特殊数值

  • NaN: Not a Number
    • 0/0也是NaN
    • NaN不等于任何值,包括它本身。 NaN === NaN // false
    • NaN与任何数(包括它自己)的运算,得到的都是NaN
    • 可以使用内置函数 isNaN() 来判断一个变量是否为 NaN
  • Infinity(正无穷)和 -Infinity(负无穷)
    • InfinityNaN比较,总是返回false
    • 四则运算,符合无穷的数学计算规则。
    • 0乘以Infinity,返回NaN;0除以Infinity,返回0Infinity除以0,返回Infinity
      • null计算时,null会转成0
    • Infinity减去或除以Infinity,得到NaN
    • 内置函数 isFinite() 来判断一个变量是否是一个有穷数 (类型为Infinity, -InfinityNaN则返回false)
    • Infinityundefined计算,返回的都是NaN
  • 正零+0和负零-0
    • 区别就是64位浮点数表示法的符号位不同,几乎等价
    • 唯一区别:(1 / +0) === (1 / -0) // false
      • 一个是Infinity一个是-Infinity

数值转换

parseInt

内置函数 parseInt() 将字符串转换为整型。该函数的第二个可选参数表示字符串所表示数字的基(进制)(2到36之间)如果第二个参数是0undefinednull,则直接忽略,返回十进制结果。

  • 会自动删除头部空格
  • 会自动将参数转换为字符串
  • 遇到不能转换的字符则停止转换,返回前面已经转换的部分(如果有小数点,只能转换整数部分)(前提是已经是字符串格式)
  • 如果第一个字符就不能转换,则返回NaN
1
2
3
4
5
6
7
8
9
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
parseInt(null) // NaN
parseInt(1.1) // 1
parseInt(1..) // NaN
parseInt('1..') // 1
  • 对于那些会自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串,因此导致一些奇怪的结果
1
2
3
4
5
6
7
parseInt(1000000000000000000000.5) // 1
// 等同于
parseInt('1e+21') // 1

parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
  • 如果parseInt的第一个参数不是字符串,会被先转为字符串。这会导致一些令人意外的结果,,对于八进制的前缀0,尤其需要注意:
1
2
3
4
5
6
7
8
9
parseInt(0x11, 2) // 1
parseInt(011, 2) // NaN
// 等同于
parseInt(String(0x11), 2)
parseInt(String(011), 2)

// 等同于
parseInt('17', 2)
parseInt(String(9), 2)
parseFloat

会自动过滤字符串前导的空格

如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回NaN

parseFloat会将空字符串转为NaN

这些特点使得parseFloat的转换结果不同于Number函数。

1
2
3
4
5
6
7
8
9
10
11
parseFloat(true)  // NaN
Number(true) // 1

parseFloat(null) // NaN
Number(null) // 0

parseFloat('') // NaN
Number('') // 0

parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
一元加法运算符
1
2
3
4
5
6
"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2
// 注意:加入括号为清楚起见,不是必需的。
+ "42"; // 42
+ "010"; // 10
+ "0x10"; // 16

字符串

  • JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。
  • 反斜杠后面跟八进制或十六进制可以表示Unicode码点
  • JavaScript 原生提供两个 Base64 相关的方法。(将任意值转成 0~9、A~Z、a-z、+/这64个字符组成的可打印字符。)
    • btoa():任意值转为 Base64 编码
    • atob():Base64 编码转为原来的值

字符串也有一些方法:

1
2
3
"hello".charAt(0); // "h"
"hello, world".replace("world", "mars"); // "hello, mars"
"hello".toUpperCase(); // "HELLO"
JS特殊字符
字符 意思
\0 Null字节
\b 退格符
\f 换页符
\n 换行符
\r 回车符
\t Tab (制表符)
\v 垂直制表符
\’ 单引号
\" 双引号
\\ 反斜杠字符(\)
\XXX 由从0到377最多三位八进制数XXX表示的 Latin-1 字符。例如,\251是版权符号的八进制序列。
\xXX 由从00和FF的两位十六进制数字XX表示的Latin-1字符。例如,\ xA9是版权符号的十六进制序列。
\uXXXX 由四位十六进制数字XXXX表示的Unicode字符。例如,\ u00A9是版权符号的Unicode序列。见Unicode escape sequences (Unicode 转义字符).
\u*{XXXXX}* Unicode代码点 (code point) 转义字符。例如,\u{2F804} 相当于Unicode转义字符 \uD87E\uDC04的简写。

模板字面量

ES6中提供了一种模板字面量(template literals),模板字符串提供了一些语法糖来帮你构造字符串。

除此之外,你可以在通过模板字符串前添加一个tag来自定义模板字符串的解析过程,这可以用来防止注入攻击,或者用来建立基于字符串的高级数据抽象。[10:1]

此外模板字面量支持多行字符串的输入

如何放置注入攻击?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Basic literal string creation
`In JavaScript '\n' is a line-feed.`

// Multiline strings
`In JavaScript this is
not legal.`

// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// Construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
Content-Type: application/json
X-Credentials: ${credentials}
{ "foo": ${foo},
"bar": ${bar}}`(myOnReadyStateChangeHandler);

对象

对象的创建

有两种简单方法可以创建一个空对象:

1
var obj = new Object();

和:

1
var obj = {};

这两种方法在语义上是相同的。第二种更方便的方法叫作“对象字面量(object literal)”法。

读取对象属性

读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。

注意,数值键名不能使用点运算符,只能使用方括号运算符。

1
2
3
4
5
6
7
var foo = {a: "alpha", 2: "two"};
console.log(foo.a); // alpha
console.log(foo[2]); // two
//console.log(foo.2); // SyntaxError: missing ) after argument list
//console.log(foo[a]); // ReferenceError: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two
  • 支持链式访问

其他

  • 查看一个对象本身的所有属性,可以使用Object.keys方法。
  • delete命令用于删除对象的属性,删除成功后返回true
  • in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值)
  • for...in循环用来遍历一个对象的全部键。
    • 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性(toString属性)。
    • 它不仅遍历对象自身的属性,还遍历继承的属性。
      • 一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。
  • with语句:操作同一个对象的多个属性时,提供一些书写的方便。

关于对象和原型的详情参见: Object.prototype. 解释对象原型和对象原型链可以参见:继承与原型链

数组

  • 数组就是键值为下标的对象

  • 清空数组的一个有效方法,就是将length属性设为0。

如果想在数组后追加元素,只需要:

1
a.push(item);

也可以直接通过下标添加:

1
2
3
4
var a=[1,2,3];
a[5]=2;
a
// [ 1, 2, 3, 1, <1 empty item>, 2 ]

数组的空位

当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)。

1
2
var a = [1, , 1];
a.length // 3
  • 上面代码表明,数组的空位不影响length属性。虽然这个位置没有值,引擎依然认为这个位置是有效的。

  • 数组的空位是可以读取的,返回undefined

    • 但是给数组某一位赋值undefined不代表那一位为空,详见下面的示例
  • 使用delete a[i]命令删除一个数组成员,会形成空位,并且不会影响length属性。

遍历有空位的数组时,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。但是使用for...of结构就不会。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
a = [3,2,,1]
b = [3,2,undefined,1]
console.log('---- for...in ----');
for (const i in a) {
console.log(i); // index
}

console.log('---- forEach ----');
a.forEach(element => {
console.log(element);
});

console.log('---- Object.keys ----');
console.log(Object.keys(a));

console.log('---- for...of ----');
for (const i of a) {
console.log(i);
}

console.log('---- undefined ----');
b.forEach(element => {
console.log(element);
});

// result:
// ---- for...in ----
// 0
// 1
// 3
// ---- forEach ----
// 3
// 2
// 1
// ---- Object.keys ----
// [ '0', '1', '3' ]
// ---- for...of ----
// 3
// 2
// undefined
// 1
// ---- undefined ----
// 3
// 2
// undefined
// 1

Array 方法的完整文档 (mozilla.org)

方法名称 描述
a.toString() 返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。
a.toLocaleString() 根据宿主环境的区域设置,返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。
a.concat(item1[, item2[, ...[, itemN]]]) 返回一个数组,这个数组包含原先 aitem1、item2、……、itemN 中的所有元素。(和push不同的是,它可以添加多个数组形式的数,也可以直接添加多个数)
a.join(sep) 返回一个包含数组中所有元素的字符串,每个元素通过指定的 sep 分隔。
a.pop() 删除并返回数组中的最后一个元素。
a.push(item1, ..., itemN) item1、item2、……、itemN 追加至数组 a
a.reverse() 数组逆序(会更改原数组 a)。
a.shift() 删除并返回数组中第一个元素。(相当于 出队
a.slice(start, end) 返回子数组,以 a[start] 开头,以 a[end] 前一个元素结尾。
a.sort([cmpfn]) 依据可选的比较函数 cmpfn 进行排序,如果未指定比较函数,则按字符顺序比较(即使被比较元素是数字)。
a.splice(start, delcount[, item1[, ...[, itemN]]]) start 开始,删除 delcount 个元素,然后插入所有的 item
a.unshift(item1[, item2[, ...[, itemN]]]) item 插入数组头部,返回数组新长度(考虑 undefined)。

控制、循环与迭代

循环与迭代 - JavaScript | MDN (mozilla.org)

lable语句

JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。[8:1]

1
2
label:
语句

标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。

标签通常与break语句和continue语句配合使用,跳出特定的循环。

1
2
3
4
5
6
7
8
9
10
11
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0

for...in语句

for...in 语句循环一个指定的变量来循环一个对象所有可枚举的属性。

Js里不推荐使用for..in来迭代数组,如果你想改变数组对象,比如添加属性或者方法,for…in 语句迭代的是自定义的属性,而不是数组的元素。[13]

这里注意和python的区别,迭代数组的话 for...of 语句,和 forEach(),是理想的选择。

for...of语句

可迭代对象(包括ArrayMapSetarguments 等等)上创建了一个循环,对值的每一个独特属性调用一次迭代。

for...in 循环遍历的结果是数组元素的下标,而 for...of 遍历的结果是元素的值:

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
console.log(i); // 输出 "0", "1", "2", "foo"
}

for (let i of arr) {
console.log(i); // 输出 "3", "5", "7"
}

// 注意 for...of 的输出没有出现 "hello"

forEach()

面试官:有了 for 循环 为什么还要 forEach ? - 文章详情 (itpub.net)

Array.prototype.forEach() - JavaScript | MDN (mozilla.org)

1
2
3
4
5
6
7
8
9
10
11
["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
// 操作 currentValue 或者 array[index]
});

var colors = ['red', 'green', 'blue'];
colors.forEach(function (color) {
console.log(color);
});
// red
// green
// blue

异常处理

详见[13:1]

1
2
3
4
5
6
7
8
openMyFile();
try {
writeMyFile(theData); //This may throw a error
}catch(e){
handleError(e); // If we got a error we handle it
}finally {
closeMyFile(); // always close the resource
}

如果finally块返回一个值,该值会是整个try-catch-finally流程的返回值,不管在trycatch块中语句返回了什么


  1. JavaScript 教程 - 网道 (wangdoc.com) ↩︎

  2. 《JavaScript权威指南》 ↩︎

  3. 微软官方 JavaScript 入门教程【完结撒花】_哔哩哔哩_bilibili ↩︎ ↩︎

  4. JavaScript | MDN (mozilla.org) ↩︎

  5. 《前端程序员面试笔试通关宝典》 ↩︎

  6. 什么是 JavaScript? - 学习 Web 开发 | MDN (mozilla.org) ↩︎

  7. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types ↩︎ ↩︎

  8. JavaScript 的基本语法 - JavaScript 教程 - 网道 (wangdoc.com) ↩︎ ↩︎

  9. 重新介绍 JavaScript(JS 教程) - JavaScript | MDN (mozilla.org) ↩︎ ↩︎

  10. 语法和数据类型 - JavaScript | MDN (mozilla.org) ↩︎ ↩︎

  11. 重新介绍 JavaScript(JS 教程) - JavaScript | MDN (mozilla.org) ↩︎

  12. 数值 - JavaScript 教程 - 网道 (wangdoc.com) ↩︎

  13. 流程控制与错误处理 - JavaScript | MDN (mozilla.org) ↩︎ ↩︎