stanford-oval/wikipedia huggingface dataset:
JavaScript语法
变量

标准JavaScript中的变量没有附加类型，因此任何值（每个值都有一个类型）可以存储在任何变量中。从ES6（该语言的第6版）开始，变量可以用var声明函数范围变量，而let或const用于块级变量。在ES6之前，变量只能用var语句声明。分配给用const声明的变量的值不能更改，但其属性可以。变量的标识符必须以字母、下划线 (_) 或美元符号 ($) 开头，而后续字符也可以是数字 (0-9)。JavaScript区分大小写，因此大写字符“A”到“Z”与小写字符“a”到“z”不同。
从JavaScript1.5 开始，可以在标识符中使用ISO 8859-1或Unicode字符（或 \uXXXXUnicode转义序列）。在某些JavaScript实现中，可以在标识符中使用at符号 (@)，但这与规范相反，并且在较新的实现中不受支持。
变量 > 作用域和提升

用var声明的变量是在函数级别的词法作用域，而用let或const声明的变量具有块级作用域。由于声明是在任何代码执行之前处理的，因此可以在代码中声明之前分配和使用变量。这被称为提升(hoisting)，它相当于在函数或块的顶部前向声明的变量。
对于var、let和const语句，只有声明被提升；赋值未被提升。因此，函数中间的var x = 1语句等效于函数顶部的var x声明语句，以及函数中间该点的{{{1}}}赋值语句。这意味着值在声明之前不能被访问；前向引用(forward reference)是不可能的。使用var变量的值在初始化之前是未定义的(undefined)。使用let或const声明的变量在初始化之前无法访问，因此之前引用此类变量会导致错误。
函数声明，它声明一个变量并为其分配一个函数，类似于变量语句，但除了可以提升声明之外，它们还提升了赋值——就好像整个语句出现在包含的函数的顶部一样——因此前向引用(forward reference)也是允许的：函数语句在包含它的函数中的位置是不相关的。这不同于在var、let或const语句中将函数表达式赋值给变量。
因而，如：
var func = function() { .. } // 仅提升声明
function func() { .. } // 声明和赋值被提升
块作用域可以通过将整个块包装在一个函数中然后执行它来产生——这被称为立即调用函数表达式模式——或者通过使用let关键字声明变量。
变量 > 声明和赋值

在作用域外声明的变量是全局变量。如果一个变量在更高的作用域中声明，它可以被子作用域(child scope)访问。
当JavaScript尝试解析标识符时，它会在本地作用域内查找。如果没有找到这个标识符，它会在下一个外部作用域中查找，依此类推，直到抵达全局变量所在的全局作用域。如果仍未找到，JavaScript将引发ReferenceError异常。
给标识符赋值时，JavaScript会通过完全相同的过程来获取此标识符；但如果在全局范围内找不到它，将在创建的作用域内创建“变量”。因此，如果给未声明的变量赋值，会被创建为一个全局变量。在全局范围内（即在任何函数体之外或在let/const的情况下为块）声明一个变量（使用关键字var），或者给一个未声明的标识符赋值，或向全局对象（通常是窗口）添加一个属性，这将创建一个新的全局变量。
请注意，JavaScript的严格模式(strict mode)禁止给未声明的变量赋值，从而避免了全局命名空间污染。
变量 > 例子

变量声明和作用域的一些例子：
var x1 = 0; // 一个全局变量，因为未在任何函数内
let x2 = 0; // 也是全局变量，因为未在任何块内

function f() {
  var z = 'foxes', r = 'birds'; // 2个局部变量
  m = 'fish'; //全局变量，因为给未声明的变量赋值

  function child() {
    var r = 'monkeys'; //为局部变量，不影响父函数中变量r的值"birds"
    z = 'penguins'; //闭包：子函数也能访问父函数中的变量
  }

  twenty = 20; //该变量在下一行声明，但在该函数内任何位置都可用，这里是在声明之前使用
  var twenty;

  child();
  return x1 + x2; //这里使用的x1和x2是全局变量
}

f();

console.log(z); // 这将抛出ReferenceError异常，因为z不可用了
for (let i = 0; i < 10; i++) console.log(i);
console.log(i); // 抛出 ReferenceError: i is not defined
for (const i = 0; i < 10; i++) console.log(i); // 抛出TypeError: Assignment to constant variable

const pi; // 抛出SyntaxError: Missing initializer in const declaration
基本数据类型

JavaScript语言提供6种基本数据类型:
Undefined
Number
BigInt
String
Boolean
Symbol
一些基本数据类型还提供一组命名值来表示类型边界的范围。这些命名值在下面的相应子节中描述。
基本数据类型 > Undefined

“undefined”值（英语：）被赋值给所有未初始化变量（英语：），在查看不存在的对象属性时也返回这个值。在布尔上下文中，未定义值被认为是假值。
注意： undefined 被认为是真正的基本数据类型。 除非显式转换，否则与在逻辑上下文中评估为false的其他类型相比，未定义的值可能会出现不可预料的行为。
var test;                         // 变量被声明但未定义，其值被赋为undefined值

var testObj = {};
console.log(test);                // test的值存在，显示为undefined
console.log(testObj.myProp);      // testObj存在，但属性不存在，显示为undefined
console.log(undefined == null);   // 未强制类型检查，显示为true
console.log(undefined === null);  // 强制类型检查，显示为false
注意：没有内建的语言字面量用于undefined。因此(x === undefined)并不是一个万无一失的放式检查一个变量是否为undefined，因为在ECMAScript 5之前的版本，如果写代码var undefined = "I'm defined now";是合法的。更鲁棒的比较方法是(typeof x === 'undefined').
下属函数不会如期望那样工作：
function isUndefined(x) { var u; return x === u; }             // 如这个...
function isUndefined(x) { return x === void 0; }               // ... 或第二个
function isUndefined(x) { return (typeof x) === "undefined"; } // ... 或第三个
调用isUndefined(my_var)会抛出ReferenceError，如果my_var是未知标识符，但typeof my_var === 'undefined'不会抛出异常。
基本数据类型 > Number

Number数据类型表示IEEE-754浮点双精度。不能精确表示一些实数或分数。如：
console.log(0.2 + 0.1 === 0.3); // displays false
console.log(0.94 - 0.01);       // displays 0.9299999999999999
因此，无论何时格式化输出，都应使用诸如toFixed()方法之类的例程对数字进行舍入。
数字可以用这些符号中的任何一种来指定：
345;    // 一个整数
34.5;   // 一个浮点数
3.45e2; // 另一个浮点数
0b1011; // 二进制整数
0o377;   // 八进制整数
0xFF;   // 十六进制整数，A-F可大写可小写
ES2021引入了数字分隔符_ (the underscore)：
1_000_000_000;    // 用于大数
1_000_000.5;      // 支持十进制
1_000e1_000;      // 支持科学计数法

//支持二进制、八进制、十六进制
0b0000_0000_0101_1011;
0o0001_3520_0237_1327;
0xFFFF_FFFF_FFFF_FFFE;

// 但是您能在数的非数字部分旁边，或开头或结尾处使用分隔符
_12; // 变量未定义（下划线使其成为变量标识符）
12_; // 语法错误（不能在数字的末尾）
12_.0; // 语法错误（在小数点旁边放置分隔符没有意义）
12._0; // 语法错误
12e_6; // 语法错误（“e”旁边，非数字。在开头放置分隔符没有意义）
1000____0000; // 语法错误（“_”旁边，非数字。一次只允许 1 个分隔符
Number类型的范围+∞, −∞和NaN(Not a Number)可以通过两个程序表达式获得：
Infinity; // 正无穷大（用-Infinity 获得负无穷大）
NaN;      // Not-A-Number值，字符串到数字转换时也作为失败返回值
Infinity 和 NaN 是数字：
typeof Infinity;   // 返回"number"
typeof NaN;        // 返回"number"
这三个特殊值对应并按照IEEE-754描述的方式运行。
Number构造函数（用作函数），或一元+或-可用于执行显式数值转换：
var myString = "123.456";
var myNumber1 = Number(myString);
var myNumber2 = +myString;
当用作构造函数时，会创建一个数值包装对象（尽管它用处不大）：
myNumericWrapper = new Number(123.456);
但是，NaN 不等于自身：
const nan = NaN;
console.log(NaN == NaN);        // false
console.log(NaN === NaN);       // false
console.log(NaN !== NaN);       // true
console.log(nan !== nan);       // true

//可用isNaN方法检查NaN
console.log(isNaN("converted to NaN"));     // true
console.log(isNaN(NaN));                    // true
console.log(Number.isNaN("not converted")); // false
console.log(Number.isNaN(NaN));             // true
基本数据类型 > BigInt

BigInts 可用于任意大的整数。特别是大于253 - 1的整数，这是JavaScript可以用 Number 原语可靠表示的最大数字，并由Number.MAX_SAFE_INTEGER常量表示。
let t = 100n;
let t1 = BigInt('100');
let t2 = BigInt('0x64');
let t3 = BigInt(100);
//这几种方法，都可以定义BigInt
Math的方法不支持BigInt。
JSON.stringify不支持BigInt，需要BigInt.prototype.toJSON = function() { return this.toString(); }后就可以支持。
toString方法支持BigInt，radix有效值是[2,36]，默认是10。
BigInt除法，结果会被截断为整数，不是浮点数。如：100n/7n;结果为14n，不是浮点数。
基本数据类型 > String

JavaScript中的字符串是一个字符序列。在JavaScript中，可以通过将一系列字符放在双引号(") 或单引号(')之间直接创建字符串（作为字面量）。此种字符串必须写在单行上，但可包含转义的换行符（如\n). JavaScript标准允许反引号字符（`，即重音符或反撇号）引用多行字符串字面量，但这仅在2016年开始的某些浏览器上支持：Firefox和Chrome，但Internet Explorer 11不支持。
var greeting = "Hello, World!";
var anotherGreeting = 'Greetings, people of Earth.';
可以使用charAt方法（由String.prototype提供）访问字符串中的单个字符。这是访问字符串中的单个字符时的首选方式，因为它也适用于非现代浏览器：
var h = greeting.charAt(0);
在现代浏览器中，可以通过与数组相同的表示法访问字符串中的单个字符：
var h = greeting[0];
但是，JavaScript字符串是不可变的：
greeting[0] = "H"; // Fails.
如果字符串具有相同的内容，则将相等运算符 ("==") 应用于两个字符串将返回 true，这意味着：具有相同的长度并包含相同的字符序列（大小写对字母很重要）。因此：
var x = "World";
var compare1 = ("Hello, " +x == "Hello, World"); // Here compare1 contains true.
var compare2 = ("Hello, " +x == "hello, World"); // Here compare2 contains false since the first characters of the second operands are not of the same case.
除非转义，否则不能嵌套相同类型的引号：
var x = '"Hello, World!" he said.'; // Just fine.
var x = ""Hello, World!" he said."; //  Not good.
var x = "\"Hello, World!\" he said."; // Works by escaping " with \"
String构造函数创建一个字符串对象（一个包装字符串的对象）：
var greeting = new String("Hello, World!");
这些对象有一个valueOf方法，返回包装在其中的原始字符串：
var s = new String("Hello !");
typeof s; // Is 'object'.
typeof s.valueOf(); // Is 'string'.
两个String对象之间的相等与字符串原语不同：
var s1 = new String("Hello !");
var s2 = new String("Hello !");
s1 == s2; // Is false, because they are two distinct objects.
s1.valueOf() == s2.valueOf(); // Is true.
基本数据类型 > Boolean

JavaScript提供了一个带有真假字面量的布尔数据类型。typeof运算符为这些基本类型返回字符串“"boolean"”。 在逻辑上下文中使用时，由于自动类型转换，0、-0、null、NaN、undefined和空字符串("")求值为false。 所有其他值（前一个列表的补集）求值为true，包括字符串"0"、"false"和任何对象。
基本数据类型 > 类型转换

使用类型检查的比较运算符(===和!==)可以避免相等比较运算符(==和!=)的自动类型强制(type coercion)。
当需要类型转换时，JavaScript会按如下方式转换Boolean、Number、String或Object操作数：
道格拉斯·克羅克福特提倡用“truthy”和“falsy”来描述各种类型的值在逻辑上下文中的行为方式，特别是在边缘情况下。在JavaScript的早期版本中，二元逻辑运算符返回一个布尔值，但现在它们返回一个操作数。在合取(a && b)时，如果左操作数为false，则返回左操作数；或在析取(a || b)时，如果左操作数为true，则返回左操作数；否则返回右操作数。对于混合了布尔操作数和number兼容操作数（包括可以计算为number的字符串，或可以计算为此类字符串的对象），比较运算符的自动类型强制可能会有所不同，因为布尔操作数将作为一个数值被比较。这可能出乎意料。表达式可以通过双重逻辑否定运算符：(!!)、使用Boolean()函数或使用条件运算符：(c ? t : f)显式转换为布尔基本类型。
// Automatic type coercion
console.log(true  ==   2 ); // false... true  → 1 !== 2 ←  2
console.log(false ==   2 ); // false... false → 0 !== 2 ←  2
console.log(true  ==   1 ); // true.... true  → 1 === 1 ←  1
console.log(false ==   0 ); // true.... false → 0 === 0 ←  0
console.log(true  ==  "2"); // false... true  → 1 !== 2 ← "2"
console.log(false ==  "2"); // false... false → 0 !== 2 ← "2"
console.log(true  ==  "1"); // true.... true  → 1 === 1 ← "1"
console.log(false ==  "0"); // true.... false → 0 === 0 ← "0"
console.log(false ==  "" ); // true.... false → 0 === 0 ← ""
console.log(false ==  NaN); // false... false → 0 !== NaN

console.log(NaN == NaN); // false...... NaN is not equivalent to anything, including NaN.

// Type checked comparison (no conversion of types and values)
console.log(true === 1); // false...... data types do not match

// Explicit type coercion
console.log(true === !!2);   // true.... data types and values match
console.log(true === !!0);   // false... data types match, but values differ
console.log( 1  ? true : false); // true.... only ±0 and NaN are "falsy" numbers
console.log("0" ? true : false); // true.... only the empty string is "falsy"
console.log(Boolean({}));    // true.... all objects are "truthy"
new运算符可用于为布尔基本类型创建对象包装器。但是，typeof运算符不返回对象包装器的boolean，它返回object。因为所有对象都求值为true，所以必须使用诸如.valueOf()或.toString()之类的方法来检索包装的值。对于Boolean类型的显式强制，Mozilla建议优先使用Boolean()函数（没有new）而不是 Boolean 对象。
var b = new Boolean(false);   // Object  false {}
var t = Boolean(b);           // Boolean true
var f = Boolean(b.valueOf()); // Boolean false
var n = new Boolean(b);       // Not recommended
n = new Boolean(b.valueOf()); // Preferred

if (0 || -0 || "" || null || undefined || b.valueOf() || !new Boolean() || !t) {
  console.log("Never this");
} else if ([] && {} && b && typeof b === "object" && b.toString() === "false") {
  console.log("Always this");
}
基本数据类型 > Symbol

ECMAScript6引入的新类型。一个Symbol是独一无二且不可变的标识符。
例如：
var x = Symbol(1);
var y = Symbol(1);
console.log(x === y); // => false

var symbolObject = {};
var normalObject = {};

// since x and y are unique,
// they can be used as unique keys in an object
symbolObject[x] = 1;
symbolObject[y] = 2;

console.log(symbolObject[x]); // => 1
console.log(symbolObject[y]); // => 2

// as compared to normal numeric keys
normalObject[1] = 1;
normalObject[1] = 2; // overrides the value of 1

console.log(normalObject[1]); // => 2

// changing the value of x does not change the key stored in the object
x = Symbol(3);
console.log(symbolObject[x]); // => undefined

// changing x back just creates another unique Symbol
x = Symbol(1);
console.log(symbolObject[x]); // => undefined
存在well known symbols。其中一个是Symbol.iterator; 如果程序实现了Symbol.iterator，则它是可迭代的：
let x = [1, 2, 3, 4]; // x is an Array
x[Symbol.iterator] === Array.prototype[Symbol.iterator]; // and Arrays are iterable

const xIterator = x[Symbol.iterator](); // The [Symbol.iterator] function should provide an iterator for x
xIterator.next(); // { value: 1, done: false }
xIterator.next(); // { value: 2, done: false }
xIterator.next(); // { value: 3, done: false }
xIterator.next(); // { value: 4, done: false }
xIterator.next(); // { value: undefined, done: true }
xIterator.next(); // { value: undefined, done: true }

// for..of loops automatically iterate values
for (const value of x) {
   console.log(value); // 1 2 3 4
}

// Sets are also iterable:
[Symbol.iterator] in Set.prototype; // true

for (const value of new Set(['apple', 'orange'])) {
   console.log(value); // "apple" "orange"
}
原生对象

JavaScript语言提供了一些原生对象(native object)。JavaScript原生对象被认为是JavaScript规范的一部分。 尽管有JavaScript环境，但这组对象应该始终可用。
原生对象 > Array

数组(array)是从Array构造函数原型化的JavaScript对象，专门设计用于存储由整数键索引的数据值。数组与基本的Object类型不同，它是具有方法和属性的原型，以帮助程序员完成日常任务（例如，join, slice和push）。
与C语言家族的编程语言一样，数组使用从零开始的索引方案：通过push方法插入空数组的值占据数组的第0个索引。
var myArray = [];            // Point the variable myArray to a newly ...
                             // ... created, empty Array
myArray.push("hello World"); // Fill the next empty index, in this case 0
console.log(myArray[0]);           // Equivalent to console.log("hello World");
数组有一个length属性，保证总是大于数组中使用的最大整数索引。如果创建具有更大索引的属性，它会自动更新。将较小的数字写入length属性将删除较大的索引。
可以使用普通对象属性访问表示法访问Array的元素：
myArray[1];  // the 2nd item in myArray
myArray["1"];
以上两个是等价的。 不能使用“点”表示法或带有替代数字表示的字符串：
myArray.1;     // syntax error
myArray["01"]; // not the same as myArray[1]
声明一个数组可用Array字面量或者Array构造函数:
let myArray;

// Array literals
myArray = [1, 2]; // length of 2
myArray = [1, 2,]; // same array - You can also have an extra comma at the end

// It's also possible to not fill in parts of the array
myArray = [0, 1, /* hole */, /* hole */, 4, 5]; // length of 6
myArray = [0, 1, /* hole */, /* hole */, 4, 5,]; // same array
myArray = [0, 1, /* hole */, /* hole */, 4, 5, /* hole */,]; // length of 7

// With the constructor
myArray = new Array(0, 1, 2, 3, 4, 5); // length of 6
myArray = new Array(365);              // an empty array with length 365
数组实现为“稀疏数组”，只有定义的元素占用了内存。设置myArray[10] = 'someThing'和myArray[57] = 'somethingOther'只为这两个元素分配了内存空间，这与任何其他对象一样。数组的length仍报告为58。数组的最大长度为4,294,967,295，对应于 32 位二进制无符号数(11111111111111111111111111111111)2。
可以使用对象声明字面量来创建其行为类似于其他语言中的关联数组对象：
dog = {color: "brown", size: "large"};
dog["color"]; // results in "brown"
dog.color;    // also results in "brown"
可以使用对象和数组声明字面量来快速创建关联数组、多维数组或两者兼有的数组。从技术上讲，JavaScript不支持多维数组，但可以使用数组数组来模仿它们：
cats = [{color: "brown", size: "large"},
    {color: "black", size: "small"}];
cats[0]["size"];      // results in "large"

dogs = {rover: {color: "brown", size: "large"},
    spot: {color: "black", size: "small"}};
dogs["spot"]["size"]; // results in "small"
dogs.rover.color;     // results in "brown"
原生对象 > Date

Date对象存储有符号的毫秒计数，零表示1970-01-01 00:00:00 UT，值域为±108 天。有几种方法可以为Date构造函数提供参数。注意，月份是从零开始的。
new Date();                       // create a new Date instance representing the current time/date.
new Date(2010, 2, 1);             // create a new Date instance representing 2010-Mar-01 00:00:00
new Date(2010, 2, 1, 14, 25, 30); // create a new Date instance representing 2010-Mar-01 14:25:30
new Date("2010-3-1 14:25:30");    // create a new Date instance from a String.
提供了抽取字段的方法，以及有用的toString:
var d = new Date(2010, 2, 1, 14, 25, 30); // 2010-Mar-01 14:25:30;

// Displays '2010-3-1 14:25:30':
console.log(d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' '
    + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds());

// Built-in toString returns something like 'Mon Mar 01 2010 14:25:30 GMT-0500 (EST)':
console.log(d);
原生对象 > Error

用Error类可以创建定制的错误消息:
throw new Error("Something went wrong.");
这可被try...catch...finally块捕获。将在异常处理节中详述。
原生对象 > Math

The Math object contains various math-related constants (for example, ) and functions (for example, cosine). (Note that the  object has no constructor, unlike  or . All its methods are "static", that is "class" methods.) All the trigonometric functions use angles expressed in radians, not degrees or grads.
Math对象包含各种与数学相关的常数（例如，π）和函数（例如，余弦）。 请注意，与Array或Date不同，Math对象没有构造函数。它的所有方法都是“静态的”，即“类”方法。所有三角函数都使用以弧度表示角度，而不是度数或百分度。
| 属性 | 返回值 四舍五入到5位数字 | 说明 |
| --- | --- | --- |
| Math.E | 2.7183 | e: 自然对数基 |
| Math.LN2 | 0.69315 | 2的自然对数 |
| Math.LN10 | 2.3026 | 10的自然对数 |
| Math.LOG2E | 1.4427 | e的以2为基的对数 |
| Math.LOG10E | 0.43429 | e的以10为基的对数 |
| Math.PI | 3.14159 | π: 圆周率 |
| Math.SQRT1_2 | 0.70711 | ½的平方根 |
| Math.SQRT2 | 1.4142 | 2的平方根 |
| 例子 | 返回值 四舍五入到5位数字 | 说明 |
| --- | --- | --- |
| Math.abs(-2.3) | 2.3 | 绝对值 |
| Math.acos(Math.SQRT1_2) | 6997785400000000000♠0.78540 rad = 45° | 反余弦 |
| Math.asin(Math.SQRT1_2) | 6997785400000000000♠0.78540 rad = 45° | 反正弦 |
| Math.atan(1) | 6997785400000000000♠0.78540 rad = 45° | 半圆反正切 ( -\pi /2至 +\pi /2) |
| Math.atan2(-3.7, -3.7) | 3001764380000000000♠−2.3562 rad = 2999764380550980765♠−135° | 全圆反正切 ( -\pi 至 +\pi ) |
| Math.ceil(1.1) | 2 | Ceiling: 近似到最小整数≥参数 |
| Math.cos(Math.PI/4) | 0.70711 | 余弦函数 |
| Math.exp(1) | 2.7183 | 指数函数: e的指数值 |
| Math.floor(1.9) | 1 | Floor:近似到最大整数≤参数 |
| Math.log(Math.E) | 1 | 基于e的自然对数 |
| Math.max(1, -2) | 1 | 最大值: (x > y) ? x : y |
| Math.min(1, -2) | 2999800000000000000♠−2 | 最小值: (x < y) ? x : y |
| Math.pow(-3, 2) | 9 | 指数运算: Math.pow(x, y)返回xy |
| Math.random() | e.g. 0.17068 | 伪随机数，值域[0,1) |
| Math.round(1.5) | 2 | 四舍五入，1.5近似到2 |
| Math.sin(Math.PI/4) | 0.70711 | 正弦 |
| Math.sqrt(49) | 7 | 平方根 |
| Math.tan(Math.PI/4) | 1 | 正切 |
原生对象 > 正则表达式

条目：正则表达式
/expression/.test(string);     // returns Boolean
"string".search(/expression/); // returns position Number
"string".replace(/expression/, replacement);

// Here are some examples
if (/Tom/.test("My name is Tom")) console.log("Hello Tom!");
console.log("My name is Tom".search(/Tom/));          // == 11 (letters before Tom)
console.log("My name is Tom".replace(/Tom/, "John")); // == "My name is John"
原生对象 > 正则表达式 > 字符类

// \d  - digit
// \D  - non digit
// \s  - space
// \S  - non space
// \w  - word char
// \W  - non word
// [ ] - one of
// [^] - one not of
//  -  - range

if (/\d/.test('0'))                   console.log('Digit');
if (/[0-9]/.test('6'))                console.log('Digit');
if (/[13579]/.test('1'))              console.log('Odd number');
if (/\S\S\s\S\S\S\S/.test('My name')) console.log('Format OK');
if (/\w\w\w/.test('Tom'))             console.log('Hello Tom');
if (/[a-zA-Z]/.test('B'))             console.log('Letter');
原生对象 > 正则表达式 > 字符匹配

// A...Z a...z 0...9  - alphanumeric
// \u0000...\uFFFF    - Unicode hexadecimal
// \x00...\xFF        - ASCII hexadecimal
// \t                 - tab
// \n                 - new line
// \r                 - CR
// .                  - any character
// |                  - OR

if (/T.m/.test('Tom')) console.log ('Hi Tom, Tam or Tim');
if (/A|B/.test("A"))  console.log ('A or B');
原生对象 > 正则表达式 > 重复

// ?   - 0 or 1 match
// *   - 0 or more
// +   - 1 or more
// {n}   - exactly n
// {n,}  - n or more
// {0,n} - n or less
// {n,m} - range n to m

if (/ab?c/.test("ac"))       console.log("OK"); // match: "ac", "abc"
if (/ab*c/.test("ac"))       console.log("OK"); // match: "ac", "abc", "abbc", "abbbc" etc.
if (/ab+c/.test("abc"))      console.log("OK"); // match: "abc", "abbc", "abbbc" etc.
if (/ab{3}c/.test("abbbc"))  console.log("OK"); // match: "abbbc"
if (/ab{3,}c/.test("abbbc")) console.log("OK"); // match: "abbbc", "abbbbc", "abbbbbc" etc.
if (/ab{1,3}c/.test("abc"))  console.log("OK"); // match: "abc", "abbc", "abbbc"
原生对象 > 正则表达式 > Anchors

// ^  - string starts with
// $  - string ends with

if (/^My/.test("My name is Tom"))   console.log ("Hi!");
if (/Tom$/.test("My name is Tom"))  console.log ("Hi Tom!");
原生对象 > 正则表达式 > 子表达式

// ( )  - groups characters

if (/water(mark)?/.test("watermark")) console.log("Here is water!"); // match: "water", "watermark",
if (/(Tom)|(John)/.test("John"))      console.log("Hi Tom or John!");
原生对象 > 正则表达式 > Flag

// /g  - global
// /i  - ignore upper/lower case
// /m  - allow matches to span multiple lines

console.log("hi tom!".replace(/Tom/i, "John"));  // == "hi John!"
console.log("ratatam".replace(/ta/, "tu"));      // == "ratutam"
console.log("ratatam".replace(/ta/g, "tu"));     // == "ratutum"
原生对象 > 正则表达式 > 高级方法

my_array = my_string.split(my_delimiter);
// example
my_array = "dog,cat,cow".split(",");      // my_array==["dog","cat","cow"];

my_array = my_string.match(my_expression);
// example
my_array = "We start at 11:30, 12:15 and 16:45".match(/\d\d:\d\d/g); // my_array==["11:30","12:15","16:45"];
原生对象 > 正则表达式 > Capturing group

var myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/;
var results = myRe.exec("The date and time are 2009-09-08 09:37:08.");
if (results) {
  console.log("Matched: " + results[0]); // Entire match
  var my_date = results[1]; // First group == "2009-09-08"
  var my_time = results[2]; // Second group == "09:37:08"
  console.log("It is " + my_time + " on " + my_date);
} else console.log("Did not find a valid date!");
原生对象 > 函数

JavaScript的每个函数是Function构造符的一个实例。当然还有async / generator函数构造符：(async()=>{})构造符得到AsyncFunction, (async function*(){})构造符得到AsyncGeneratorFunction, (function*(){})构造符得到GeneratorFunction。
// x, y is the argument. 'return x + y' is the function body, which is the last in the argument list.
var add = new Function('x', 'y', 'return x + y');
add(1, 2); // => 3
上述加法函数也可定义为函数表达式:
var add = function(x, y) {
  return x + y;
};
add(1, 2); // => 3
ES6中，增加了箭头函数语法(arrow function syntax)。与function() {}表达式不同，它们还保留全局对象的this而不是从调用它的位置/调用时的值来继承它。
var add = (x, y) => {return x + y;};
// values can also be implicitly returned (i.e. no return statement is needed)
var addImplicit = (x, y) => x + y;

add(1, 2); // => 3
addImplicit(1, 2) // => 3
对于需要提升的函数，专门的表达式：
function add(x, y) {
  return x + y;
}
add(1, 2); // => 3
提升允许你在声明之前使用它：
add(1, 2); // => 3, not a ReferenceError
function add(x, y) {
  return x + y;
}
函数实例可具有属性和方法：
function subtract(x, y) {
  return x - y;
}

console.log(subtract.length); // => 2, arity of the function (number of arguments)
console.log(subtract.toString());

/*
"function subtract(x, y) {
  return x - y;
}"
*/
运算符

'+'运算符重载：它用于字符串连接和算术加法。 当无意中混合字符串和数字时，这可能会导致问题。 作为一元运算符，它可以将数字字符串转换为数字。
// Concatenate 2 strings
console.log('He' + 'llo'); // displays Hello

// Add two numbers
console.log(2 + 6);  // displays 8

// Adding a number and a string results in concatenation (from left to right)
console.log(2 + '2');    // displays 22
console.log('$' + 3 + 4);  // displays $34, but $7 may have been expected
console.log('$' + (3 + 4)); // displays $7
console.log(3 + 4 + '7'); // displays 77, numbers stay numbers until a string is added

// Convert a string to a number using the unary plus
console.log(+'2' === 2); // displays true
console.log(+'Hello'); // displays NaN
类似地， '*'运算符也是重载的：可以把字符串转为数。
console.log(2 + '6'*1);  // displays 8
console.log(3*'7'); // 21
console.log('3'*'7'); // 21
console.log('hello'*'world'); // displays NaN
运算符 > 算术运算符

JavaScript支持下述二元算术运算符：
| --- | --- |
+: 加法
-: 加法
*: 乘法
/: 除法(返回浮点值)
%: 求余(返回余数)
**: 指数
JavaScript支持下述酉算术运算符:
| --- | --- |
+: 字符串转数
-: 符号取反
++: 前增或后增
--: 前减或后减
例如：
var x = 1;
console.log(++x); // x becomes 2; displays 2
console.log(x++); // displays 2; x becomes 3
console.log(x);  // x is 3; displays 3
console.log(x--); //  displays 3; x becomes 2
console.log(x);  //  displays 2; x is 2
console.log(--x); //  x becomes 1; displays 1
模运算符显示除以模数后的余数。 如果涉及负数，则返回值取决于操作数。
var x = 17;
console.log(x%5); // displays 2
console.log(x%6); // displays 5
console.log(-x%5); // displays -2
console.log(-x%-5); // displays -2
console.log(x%-5); // displays 2
要始终返回非负数，请重新添加模数并再次应用模运算符:
var x = 17;
console.log((-x%5+5)%5); // displays 3
运算符 > 赋值复合运算符

| --- | --- |
=: 赋值
+=: 加法赋值
-=: 减法赋值
*=: 乘法赋值
/=: 除法赋值
%=: 求余赋值
**=: 指数赋值
基本类型的赋值：
var x = 9;
x += 1; 
console.log(x); // displays: 10
x *= 30;
console.log(x); // displays: 300
x /= 6;
console.log(x); // displays: 50
x -= 3;
console.log(x); // displays: 47
x %= 7;
console.log(x); // displays: 5
对象类型的赋值：
/**
 * To learn JavaScript objects...
 */
var object_1 = {a: 1};		// assign reference of newly created object to object_1
var object_2 = {a: 0};
var object_3 = object_2;	// object_3 references the same object as object_2 does
	 
object_3.a = 2;
message();	        	// displays 1 2 2
	 
object_2 = object_1;		// object_2 now references the same object as object_1
	        	        // object_3 still references what object_2 referenced before
message();		        // displays 1 1 2
	 
object_2.a = 7;  	        // modifies object_1
message();		        // displays 7 7 2

object_3.a = 5;                 // object_3 doesn't change object_2
message();	                // displays 7 7 5

object_3 = object_2;	
object_3.a=4;                  // object_3 changes object_1 and object_2
message();                     // displays 4 4 4

/**
 * Prints the console.log message
 */
function message() {
	console.log(object_1.a + " " + object_2.a + " " + object_3.a);
}