Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

js基础

介绍

js(JavaScript)是用于 web 开发的 3 门语言中的一门。
3 门语言语言与其作用分别为:

  1. HTML 定义了网页的内容
  2. CSS 描述了网页的布局
  3. JavaScript 控制了网页的行为

用法

HTML 中的 Javascript 脚本代码必须位于 <script></script> 标签之间。
Javascript 脚本代码可被放置在 HTML 页面的 <body><head> 部分中。
如需在 HTML 页面中插入 JavaScript,使用 <script> 标签。
<script></script> 会告诉 JavaScript 在何处开始和结束。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<script>
//Javascript语句
</script>
</head>
<body>
<script>
//Javascript语句
</script>
</body>
</html>

可以把脚本保存到外部文件中。外部文件通常包含被多个网页使用的代码。
外部 JavaScript 文件的文件扩展名是 .js
如需使用外部文件,在 <script> 标签的 "src" 属性中设置 .js 文件。
<script> 标签还可以设置一些属性:

  • async:脚本立刻被并行解析和执行。对于 DOM 操作可能会在 DOM 未加载完成的时候触发导致失效。
  • defer:脚本是在文档被解析后,但在触发 DOMContentLoaded 事件之前执行的。
    本属性不应在缺少 src 属性的情况下使用将不会生效。
    模块脚本默认是 defer 的。
1
2
3
4
5
6
<!DOCTYPE html>
<html>
<body>
<script defer src="对应的JavaScript文件名.js"></script>
</body>
</html>

输入/输出

输入

JavaScript 可以通过不同的方式来输入数据:

  • 使用prompt()弹出输入框
    prompt("输入提示","提示文本"),两参数都可以省略。
    返回一个包含用户输入文本的字符串(string),或 null
    可以使用Number(prompt())+prompt()转化成数字(Number)。
  • 使用confirm()弹出确认框
    confirm("输入提示"),参数可以省略。
    返回一个布尔(Symbol)类型的变量。

对话框是模态窗口——它们阻止用户访问程序界面的其他部分,直到对话框被关闭。

1
2
3
4
// 将输入数据打印到控制台
console.log(prompt("输入提示","提示文本"));
// 将true或false输出到控制台
console.log(confirm('带确认选项输入提示'));

输出

JavaScript 可以通过不同的方式来输出数据:

  • 使用 window.alert() 弹出警告框。

  • 使用 document.write() 方法将内容写到 HTML 文档中。

  • 使用 innerHTML 写入到 HTML 元素。

  • 使用 console.log() 写入到浏览器的控制台。
    其中使用 document.write() 可以向文档写入内容。
    但如果在文档已完成加载后执行 document.write,整个 HTML 页面将被覆盖。
    console.log()打印的内容,在浏览器的控制台中,使用 F12 来启用调试模式查看内容。

1
2
3
4
5
6
7
window.alert("警告框弹出的内容");
// 但如果在文档已完成加载后执行 document.write
// 整个 HTML 页面将被覆盖。
document.write("写入的内容");
document.getElementById("demo").innerHTML = "修改段落的内容";
// 在浏览器中使用 F12 来启用调试模式 看到内容
console.log("控制台打印内容");

字面量/变量

字面量

一般固定值称为字面量。
3.14"双引号包裹字符串"'单引号包裹字符串'
数组[40, 100, 1, 5, 25, 10]
函数function myFunction(a, b) { return a * b;}
对象{firstName:"XX", age:50}

变量

变量是用于存储信息的”容器”。
变量名必须以字母或 $_符号开头且大小写敏感。
JavaScript 中使用 varletconst关键词来声明变量。
通过 var 定义的变量会被提升到顶端

1
2
3
4
5
6
var 变量名;
// 变量声明之后,该变量是空的(undefined)。
// 如需使用等号向变量赋值
变量名=123;
// 也可以在声明变量时对其赋值
var 变量名=123;

使用 let 关键字声明变量,其只在 let 命令所在的代码块 {} 内有效。
通过 let 定义的变量不会被提升到顶端,在声明 let 变量之前就使用它会导致 ReferenceError

1
2
3
4
5
6
7
8
9
10
// 这里输出 x 为 10
var x = 10;
console.log(x);
{
// 这里输出 x 为 2
let x = 2;
console.log(x);
}
// 这里输出 x 为 10
console.log(x);

使用 const 定义的变量与 let 变量类似,但不能重新赋值。
通过 const 定义的变量不会被提升到顶端,const 变量在声明之前使用将导致 ReferenceError

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 这里输出 x 为 1,2,3
var x = [1, 2, 3];
console.log(x);
{
// 这里输出 x 为 2,4,6
const x = [2, 4, 6];
console.log(x);
// 无法重新赋值
// x = [1, 3, 5];
// 可以通过访问元素修改值
x[0] = 10;
console.log(x);
}
// 这里输出 x 为 1,2,3
console.log(x);

运算符

以下是 JavaScript 运算符优先级表

优先级 运算符 名称/含义 形式
1 () 表达式分组 (表达式)
2 . 成员选择(对象) 对象.成员名
2 [] 数组下标 数组名[常量表达式]
2 () 函数调用 函数名()
2 new 创建 new Date()
3 ++ 后缀递增 i++
3 后缀递减 i–
4 ++ 前缀递增 ++i
4 前缀递减 –i
4 ! 逻辑否 !(x==y)
4 typeof 类型 typeof x
5 ** 求幂 (ES7) 10 ** 2
6 * 10 * 5
6 / 10 / 5
6 % 取余 10 % 5
7 + 10 + 5
7 - 10 - 5
8 << 左位移 x << 2
8 >> 右位移 x >> 2
8 >>> 右位移(无符号) x >>> 2
9 < 小于 x < y
9 <= 小于或等于 x <= y
9 > 大于 x > y
9 >= 大于或等于 x >= y
9 in 对象中的属性 “PI” in Math
9 instanceof 对象的实例 instanceof Array
10 == 相等 x == y
10 === 严格相等 x === y
10 != 不相等 x != y
10 !== 严格不相等 x !== y
11 & 按位与 x & y
12 ^ 按位异或 x ^ y
13 | 按位或 x | y
14 && 逻辑与 x && y
15 || 逻辑或 x || y
16 ? : 三目运算符 表达式1?表达式2:表达式3
17 = 赋值 x = y
17 += 加后赋值 x += y
17 -= 减后赋值 x -= y
17 *= 乘后赋值 x *= y
17 %= 取余后赋值 x %= y
17 <<= 左位移后赋值 x <<= y
17 >>= 右位移后赋值 x >>= y
17 >>>= 右位移(无符号)后赋值 x >>>= y
17 &= 按位与赋值 x &= y
17 ^= 按位异或后赋值 x ^= y
17 |= 按位或赋值 x |= y
18 yield 暂停函数 yield 函数名
19 , 逗号 7 , 8

==比较,会自动转换数据类型再比较,很多时候,会得到非常诡异的结果。而===比较,不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。

控制流

js的控制流与其他语言相似。
与c语言相似js的控制流可以省略{}运行其之下的第一条语句。

while语句

while语句反复执行一段代码,直到给定的条件为假为止。

1
2
3
while(条件){
循环体
}

do while语句

do while语句与while差不多,只不过while是在每次开始判断条件,而do while在每次结束判断。

1
2
3
do{
循环体
}while(条件)

for语句

while语句在循环体中递增变量非常的频繁,所以专门定义了第二种循环语句for语句来简化这种模式。
其中发拥有for··infor··of两种变体。
for··in:遍历序列中的可枚举属性的属性名,包括从原型链上继承的。
for··of:遍历可迭代元素。

1
2
3
4
5
6
7
8
9
10
11
for(初始化语句;循环条件;表达式){
循环体
}
//for··in遍历序列中的可枚举属性,包括从原型链上继承的
for(定义变量 in 序列){
循环体
}
//for··of遍历可迭代元素
for(定义变量 of 序列){
循环体
}

for ... inArray的循环得到的是String而不是Number

if语句

用于条件执行

1
2
3
4
5
6
7
if(表达式1){
分支1
}else if(表达式2){
分支2
}else{
分支3
}

switch语句

提供了一种便利的在若干个选项中做出选择的语句。
case标签:必须是整形常量表达式,如果表达式与某个case标签匹配成功,程序从该标签后的第一条开始执行,直到switch结尾或遇到一条break语句为止。
default标签:在没有任何一个case标签匹配上switch表达式的值,程序将执行default标签后的语句。

1
2
3
4
5
6
7
8
9
10
11
switch(表达式){
case 值一:
值一语句
break;
case 值二:
值二语句
break;
default:
语句
break;
}

break语句

break语句负责终止离它最近的while、do while、for或switch语句,并从这些语句后的第一条语句开始继续执行。

continue语句

continue语句负责终止最近的循环中的当前迭代立即开始下一次迭代,只能用于for、while和do while中。

try语句

try语句负责捕获处理异常。

1
2
3
4
5
6
7
try {
tryStatements; // 可能抛出异常的语句
} catch (exceptionVar) { // 要捕获的异常类型
catchStatements; // 处理异常语句
} finally {
finallyStatements; // 无论是否捕获异常都会执行的语句
}

数据类型

js中数据类型分为基本类型与引用数据类型。

  • 值类型(基本类型):
    字符串(string)、数字(number)、BigInt、布尔(boolean)、空(null)、未定义(undefined)、symbol
  • 引用数据类型(对象类型):
    数组(Array)、函数(Function)、对象(Object)等。
    还有两个特殊的对象:正则(RegExp)和日期(Date)。

js中拥有动态类型。这意味着相同的变量可用作不同的类型。

1
2
3
var x;          // x 为 undefined
var x = 5; // 现在 x 为数字
var x = "XXX"; // 现在 x 为字符串

类型判断

变量的数据类型可以使用 typeof 操作符来查看。
null数组object类型。
使用Object.prototype.toString.call()的方式更为准确

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
console.log("xxx", typeof "xxx");   // xxx string
typeof 3.14; // 3.14 'number'
typeof false; // false 'boolean'
typeof null; // null 'object'
typeof [1, 2, 3, 4]; // Array(4) 'object'
typeof { name: 'xxx', age: 34 }; // Object 'object'
typeof function name(params) { }; // ƒ name(params){} 'function'
typeof Date(); // 20xx xx:xx:xx string
typeof /runoob/i; // /runoob/i 'object'

console.log(Object.prototype.toString.call(1)); //[object Number]
Object.prototype.toString.call("HELLO WORLD"); //[object String]
Object.prototype.toString.call(null); //[object Null]
Object.prototype.toString.call(undefined); //[object Undefined]
Object.prototype.toString.call(true); //[object Boolean]
Object.prototype.toString.call(false); //[object Boolean]
Object.prototype.toString.call({name:"xiaoming"}); //[object Object]
Object.prototype.toString.call(function(){}); //[object Function]
Object.prototype.toString.call([1,2,3,"a"]); //[object Array]

字符串(String)

一个字符串用于存储一系列字符就像"xxx"
字符串可以使用单引号或双引号包裹。
在字符串中使用转义字符(\)来使用会干扰代码的符号。如"/等。
可以使用位置(索引)可以访问字符串中任何的字符。
一些常用的属性与方法:

属性/方法 介绍
String.length 返回字符串的长度
String.indexOf(str) 返回字符串第一次出现str的位置下标
若未找到str则返回-1,大小写敏感
String.lastIndexOf(str) 返回字符串最后一次出现str的位置下标
若未找到str则返回-1,大小写敏感
String.match(str) str可以是正则,判断中字符串是否存在str
若存在返回str,若否返回null,大小写敏感
String.replace(str1,str2) 返回将str1替换为str2的字符串,若不存在str1则返回原本字符串
str1可以为正则,此操作不会改变原本字符串
String.toUpperCase() 返回将转化成大写的字符串
此操作不会改变原本字符串
String.toLowerCase() 返回将转化成小写的字符串
此操作不会改变原本字符串
String.split(str) 返回根据str分割的数组,若str""则每个以每个字符分割str可以为正则
此操作不会改变原本字符串
String.search(regexp) 匹配成功返回正则在字符串中首次匹配的索引,否则,返回 -1。
String.substring(indexStart, indexEnd) indexStart:返回字符串的开始索引。
indexEnd:可选,返回字符串的结束索引。
返回截取的字符串。
String.charAt(index) 返回字符串中指定下标index的字符
String.trim() 返回新字符串,表从 str 的开头和结尾去除空白字符后的结果。
1
2
3
4
5
6
7
8
9
10
11
var txt = "Hello World!";
// 12
document.write(txt.length);
// 6
document.write(txt.indexOf("W"));
// 7
document.write(txt.lastIndexOf("o"));
// o
document.write(txt.match("o"));
// null
document.write(txt.match("A"));

数字(Number)

js不定义不同类型的数字,意味着数字不分为整数类型和浮点型类型。
IEEE754 标准定义的 64 位浮点格式表示数字。
能表示最大值(Number.MAX_VALUE)为 ±1.7976931348623157e+308
最小值(Number.MIN_VALUE)为 ±5e-324
其中 0 到 51 存储数字(片段),52 到 62 存储指数,63 位存储符号。
在不使用小数点或指数计数法时数字最多为 15 位。小数的最大位数是 17。
若前缀为 0,则解释为八进制数,若为 0x,则解释为十六进制数。
当数字运算结果超过了数字上限,结果为无穷大(Infinity),其有正负两种表现形式。基于无穷大的加、减、乘和除运算结果还是无穷大,但保留正负号。
NaN 表示非数字值的特殊值。
一些常用的属性与方法:

属性/方法 介绍
Number.parseInt(str, int) 返回按照 int进制转化str的数字
int可以省略,函数将会根据str开头判断进制
Number.isInteger(Num) 判断Num是否为NaN否为整数。
Number.isNaN(Num) 判断Num是否为NaN
若是返回true否返回false
Number.prototype.toString(int) 返回按照 int进制转化Number的字符串
Number.prototype.toFixed(digits) digits:保留小数点后的位数。
返回该数字保留digits位小数的字符串。

BigInt

要精确表示比2^53还大的整数,可以使用内置的BigInt类型,它的表示方法是在整数后加一个n,或使用BigInt()Number字符串转换成BigInt
使用BigInt可以正常进行加减乘除等运算,结果仍然是一个BigInt,但不能把一个BigInt和一个Number放在一起运算。

1
2
3
4
5
6
var bi1 = 9223372036854775807n;
var bi2 = BigInt("0x7fffffffffffffff");
// 1564, 除法运算结果仍然是BigInt
console.log(bi1 / bi2);
// Uncaught TypeError: Cannot mix BigInt and other types
console.log(bi1 + 3456789);

null和undefined

undefined:表示一个变量声明了但未赋值,或者一个对象属性不存在。
其会被解析成基本类型undefined,所以typeof undefined 的结果是基本类型'undefined'。可判断函数参数是否传递。
null:表示一个空值。其会被解析成一个指向空的对象指针,所以 typeof null 的结果是对象类型 'object'据说是bug。可以利用这样的特性先声明一个对象,之后再赋值。当没有指向堆中对象的指针时,堆中对象会被回收

symbol

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,使用了一个他人提供的对象,想为这个对象添加新的方法,新方法的名字有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
通过Symbol()函数生成,可以接受一个字符串作为参数,表示对实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
如果参数是一个对象,就会调用该对象的toString方法,将其转为字符串。
Symbol 值不能与其他类型的值进行运算,可以转化成字符串或布尔类型。

1
2
3
4
5
6
7
let s = Symbol();
typeof s // "symbol"
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
Boolean(s1) // true

类型转化

使用String(变量)变量.toString()方法可以将除了nullundefined变量转化成字符串。

1
2
3
4
5
6
7
8
var num = 123;
var arr = [1, 2, 3];
var obj = new Object();
var abc = new Object("abc");
num.toString();// 123
arr.toString();// 1,2,3
obj.toString();// [Object,object]
abc.toString();// abc

使用Number(变量)可以将纯数字的字符串,则转换为数字返回,若有非法的数字,则转换为NaN返回,若字符串是一个空串,或空格则转换为0返回。
parseInt(变量) 只返回有效整数,parseFloat(变量)返回包含小数的的有效浮点数。
若对非String使用以上操作会先将其转换为String,然后再操作。

1
2
3
4
var num = "123.456";
Number(num); //123.456
parseInt(num); //123
parseFloat(num); //123.456

对象(Object)

对象(Object)是一种无序的集合数据类型,它由若干键值对组成。
所有引用数据类型都继承自Object

构建

用一个{...}表示一个对象,键值对以xxx: xxx形式申明用,隔开。
或使用new Object()来构造一个对象。

1
2
var obj={};
var obj = new Object();

还可以用一种构造函数的方法来创建对象。先定义一个构造函数。之后可以用关键字new来调用这个函数,并返回一个对象。
如果不写new,就是一个普通函数,返回undefined。如果写了new,它就是一个构造函数,绑定的this指向新创建的对象,并默认返回this

1
2
3
4
5
6
7
8
9
10
function Student(name) {
this.name = name;
this.hello = function () {
alert('Hello, ' + this.name + '!');
}
}

let xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!

操作

通过.操作符访问属性,但属性名包含特殊字符必须用["属性名"]来访问。
obj.属性名;/obj["属性名"]
可以自由地给一个对象添加或删除属性。

1
2
3
4
5
6
7
8
9
let xiaoming = {
name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错

检测对象是否拥有某一属性,可以用in操作符。

1
2
3
4
5
let xiaoming = {
name: '小明'
};
'name' in xiaoming; // true
'grade' in xiaoming; // false

如果in判断一个属性存在,这个属性不一定就是对象的,它可能是继承得到的。
判断一个属性是否是对象自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法。

1
2
3
4
5
let xiaoming = {
name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

当不使用对象时可以选择将对象设置null来将其回收。

1
obj=null;

属性描述符

使用 Object.getOwnPropertyDescriptor(对象,属性名) 来获取对象对应属性的属性表述符。
对象中存在的属性描述符有两种主要类型:数据描述符访问器描述符

  • 数据描述符是一个具有可写或不可写值的属性。
  • 访问器描述符是由 getter/setter 函数对描述的属性。描述符只能是这两种类型之一,不能同时为两者。

数据描述符和访问器描述符都是对象。它们共享以下可选键:

  • configurable:属性的类型能否在数据属性和访问器属性之间更改、删除,默认为 false。
  • enumerable:可枚举,默认为 false。

数据描述符还具有以下可选键值:

  • value:属性值。可以是数字、对象、函数等。默认值为 undefined。
  • writable:能否使用赋值运算符更改,则为 false。

访问器描述符还具有以下可选键值:

  • get:用作属性 getter 的函数,如果没有 getter 则为 undefined。当访问该属性时,将不带参地调用此函数,并将 this 设置为通过该属性访问的对象。返回值将被用作该属性的值。
  • set:用作属性 setter 的函数,如果没有 setter 则为 undefined。当该属性被赋值时,将调用此函数,并带有一个参数,并将 this 设置为通过该属性分配的对象。

若描述符没有 valuewritablegetset 键中的任何一个,它将被视为数据描述符。
若描述符同时具有 [valuewritable] 和 [getset] 键,则会抛出异常。
这些属性不一定是描述符本身的属性。继承的属性也会被考虑在内。

静态方法

Object有一些静态方法,如下:

静态方法 介绍
Object.assign(target, ...sources) target:目标对象,修改后将作为返回值。
...sources:一个或多个包含要应用的属性的源对象。。
...sources中的所有可枚举自有属性的值复制到目标对象中,并返回修改后的目标对象。
Object.create(proto, propertiesObject) proto:新创建对象的原型对象。
propertiesObject:可选,。
返回使用指定的原型对象和属性创建一个新对象。
Object.defineProperties(obj, props) obj:在其上定义或修改属性的对象。
props:包含键表示要定义或修改的属性的名称,每个值是描述该属性的对象。
在一个对象上添加多个新的属性或修改现有属性,并返回该对象。详情
Object.defineProperty(obj, prop, descriptor) obj:要定义属性的对象。
prop:符串或 Symbol:要定义或修改的属性键。
descriptor:要定义或修改的属性的描述符。
返回传入的对象,其指定的属性已被添加或修改。
Object.entries(obj) obj:对象。
返回一个数组,包含给定对象自有的可枚举字符串键属性的键值对[key, value]。
Object.freeze(obj) obj:对象。
冻结并返回对象,其他代码不能删除或更改其任何属性。
Object.fromEntries(iterable) iterable:可迭代对象。
返回新对象,其属性由可迭代对象的条目给定。
Object.getOwnPropertyDescriptor(obj, prop) obj:要查找属性的对象。
prop:要检索其描述的属性的名称或 Symbol
若指定的属性存在于对象上,返回其属性描述符,否则返回 undefined
Object.getOwnPropertyDescriptors(obj) obj:要查找属性的对象。
返回一个包含对象所有自有属性的属性描述符的对象。
Object.getOwnPropertyNames(obj) obj:目标对象。
返回对象上找到的自有属性对应的字符串数组。
Object.getOwnPropertySymbols(obj) obj:目标对象。
返回对象上找到的自有属性对应的Symbols数组。
Object.getPrototypeOf(obj) obj:目标对象。
返回对象的原型,即内部的[[Prototype]] 属性。
Object.hasOwn(obj, prop) obj:目标对象。
prop:属性的名称或 Symbol
若指定属性是指定对象的自有属性,返回 true。若该属性是继承的或不存在,返回 false。
Object.is(obj1,obj2) 比较两个值是否相同。不等价于 === 。唯一区别在于它们处理带符号的 0NaN 值的时候。=== 将数值 -0+0 视为相等、将 NaN 视为彼此不相等,该方法则相反。
Object.isExtensible(obj) obj:目标对象。
判断对象是否可扩展。
Object.isFrozen(obj) obj:目标对象。
判断对象是否已经冻结。
Object.isSealed(obj) obj:目标对象。
判断对象是否已经封闭。
Object.keys(obj) obj:目标对象。
返回一个包含所有给定对象自有可枚举字符串属性名称的数组。
Object.preventExtensions(obj) obj:目标对象。
将对象变得不可扩展,并返回。
Object.seal(obj) obj:目标对象
。将对象变得密封,并返回。
Object.setPrototypeOf(obj, prototype) obj:目标对象。
prototype:新原型。
设置对象的原型,并返回。
设置对象的原型是一个很慢的操作,使用 Object.create() 创建一个具有所需 [[Prototype]] 属性的新对象是更加合理的。
Object.values(obj) obj:目标对象。
返回对象所有自有可枚举字符串属性的值的数组。

实例属性

这些属性在 Object.prototype 上定义,被所有 Object 实例所共享。

属性 介绍
Object.prototype.__proto__ 已弃用指向实例对象在实例化时使用的原型对象。
Object.prototype.constructor 创建该实例对象的构造函数。

实例方法

方法 介绍
Object.prototype.hasOwnProperty(prop) prop:属性的字符串或者 Symbol。
对象自身是否包含指定的属性,并不会查找原型链上继承来的属性。
Object.prototype.isPrototypeOf(object) object:要搜索其原型链的对象。
该方法所调用的对象是否在指定对象的原型链中。
Object.prototype.propertyIsEnumerable(prop) prop:属性的字符串或者 Symbol。
属性是否是对象的可枚举自有属性。
Object.prototype.toLocaleString() 返回的 this.toString() 的返回值。
Object.prototype.toString() 返回一个代表该对象的字符串。
Object.prototype.valueOf() 返回指定对象的基本类型值。

class

ES6开始关键字class正式被引入。目的就是让定义类更简单。class中使用constructor来建立构造函数。
与其他语言一样使用extends来继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('Hello, ' + this.name + '!');
}
}

let xiaoming = new Student('小明');
xiaoming.hello(); //小明

class PrimaryStudent extends Student {
constructor(name, grade) {
super(name); // 用super调用父类的构造方法!
this.grade = grade;
}

myGrade() {
alert('I am at grade ' + this.grade);
}
}

还新加入了:静态关键字static与私有关键字#
静态关键字static定义的方法会成为构造函数的属性,可以通过类名调用,不需要实例化。
私有关键字#定义的只有在类中才能调用。
以下是一个应用静态与私有实现单例的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//创建单例
class SingleTon {
//添加静态私有属性
static #instanse;
constructor(){

}
//添加静态方法
static getInstanse() {
//判断静态私有属性内是否有实例,如果没有就创建一个并返回,如果有就直接返回
if (this.#instanse === undefined) {
this.#instanse = new SingleTon();
}
return this.#instanse;
}
}

const sing1 = SingleTon.getInstanse();
const sing2 = SingleTon.getInstanse();
console.log(sing1 === sing2); //true

原型

原型和原型链都是来源于对象而服务于对象的概念。
每个对象都有原型,原型也是对象,也有它自己的原型,一层一层,组成原型链。
访问对象属性、方法时,若对象本身找不到,继续在原型链上一层一层找。
对象可以分为对象原型、对象构造器与对象实例。
对象构造器通过prototype获取到对象原型,对象原型通过constructor获取到对象构造器。
对象构造器通过new创建对象实例。
对象实例通过Object.getPrototypeOf(obj)Object.setPrototypeOf(原原型对象,替换原型对象)方法获取与设置对象原型。
对象实例也可以通过__proto__属性获取对象原型,但不推荐被使用。
静态的方法与属性挂载在对象构造器上,普通方法挂载在对象原型上,普通属性挂载在实例对象上。
js原型对象

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
class A {
static A_a = 1;
#A_b = 2;
constructor() {
this.A_c = 3;
}
getA_d() { }
static getA_e() { }
}
let a = new A(), b = new A();
a.A_a = 4, a.A_b = 5, a.A_c = 6;

/*
A_a:1, getA_e:ƒ getA_e(), name:"A",
prototype:{
getA_d:ƒ getA_d(),
constructor:class A, ...
}
*/
console.dir(A);

/*
A_a:4; A_b:5; A_c:6; #A_b:2;
prototype:{
getA_d: ƒ getA_d(),
constructor:{
A_a:1, getA_e:ƒ getA_e(), name:"A", ...
}, ...
}
*/
console.dir(a);

/*
A_c:3, #A_b:2,
prototype:{
getA_d: ƒ getA_d(),
constructor:{
A_a:1, getA_e:ƒ getA_e(), name:"A", ...
}, ...
}
*/
console.dir(b);

数组(Array)

介绍

js中的数组不同与其他语言,其可以存储包含任意不同的数据类型,而非特定的一种类型。
其使用方括号加索引(下标)来获取数组中的元素:数值[索引],或使用.at(索引)
可以使用方括号将元素包裹用,分隔来创建一个数组:var arr = [xxx,xxx,xxx],或使用构造函数。
数组的 length 属性和数值属性是连接的。增加 length 会通过添加空槽(undefined)来扩展数组。减少 length 属性会删除元素。
length 属性为 0 到 253-1 之间的范围。NaN变成 0 。
其被设置为大于 2^32 时就会抛出错误,大于 2^53-1 时,所有内置方法都将抛出 TypeError
索引超出范围会导致数组大小自动调整。

1
2
3
4
5
6
7
let arr = ['A', 'B', 'C'];
arr[5] = 'x';
console.log(arr); // ['A', 'B', 'C', undefined, undefined, 'x']
arr.length = 1;
console.log(arr);//['A']
arr.length = 4;
console.log(arr); // ['A', undefined, undefined, undefined]

构造函数

构造函数 Array() 用于创建 Array 对象。
调用 Array() 时可以使用或不使用 new。两者都会创建一个新的 Array 实例。

1
2
3
// 二者等价
var arr = new Array();
var arr = Array();

下面是构造函数的一些重载:

重载 介绍
Array() 返回一个默认的数组
Array(元素0) 返回一个包含元素0的数组
Array(元素0, 元素1, /… ,/ 元素N) 返回一个包含元素0到元素N的数组
Array(int) 返回一个包含int个undefined的数组,
int不在 0 到 2^32-1 (包括)之间会触发RangeError异常

静态方法

方法 介绍
Array.from(arrayLike, mapFn, thisArg) arrayLike:想要转换成数组的类数组或可迭代对象。
mapFn:可选,调用数组每个元素的函数,可接收元素项与下标两个参数。将返回值增加到数组中。
thisArg:可选,执行 mapFn 时用作 this 的值。
从可迭代或类数组对象创建一个新的浅拷贝数组实例并返回。
Array.fromAsync(arrayLike, mapFn, thisArg) 参数同上。
返回 Promise,其兑现值是一个新的 Array 实例。
Array.isArray(value) value:需要检测的值。
判断 value 否是一个数组。
Array.of(...element) ...element:用于创建数组的元素。
通过可变数量的参数创建一个新的 Array 实例。

实例属性

以下属性在 Array.prototype 上定义,并由所有 Array 实例共享。

属性 介绍
Array.prototype.constructor 创建实例对象的构造函数。对于 Array 实例,初始值是 Array 构造函数。
Array.prototype[Symbol.unscopables] 一个 null 原型对象。
Array.prototype.length 返回数组中元素的数量。是每个 Array 实例自有的属性。

实例方法

方法 介绍
Array.prototype.concat(value0, value1, /… ,/ valueN) value0~N:(可选)数组或值,将被合并到一个新的数组中。
返回新的数组实例。若省略所有 valueN 参数,则返回调用此方法的现存数组的一个浅拷贝
Array.prototype.copyWithin(target, start, end) target:序列开始替换的目标位置。
start:复制元素序列的起始位置。
end:复制元素序列的结束位置。
浅复制数组的一部分到同一数组中的另一个位置,并返回。不会改变原数组的长度。
Array.prototype.entries() 返回数组迭代器对象,包含每个索引的键值对。
Array.prototype.fill(value, start, end) value:用来填充数组元素的值。
start:可选,默认0。开始填充的索引。
end:可选,默认数组长度。结束填充索引,不包含其自身。
返回修改后的数组。
Array.prototype.filter(callbackFn, thisArg) callbackFn:为数组中的每个元素执行的函数。其返回真将元素保留在结果数组中,假则相反。接收:正在处理的元素、索引和数组本身。三个参数
thisArg:可选,执行时用作 this 的值。
返回通过函数的元素的浅拷贝组成的数组。
Array.prototype.find(callbackFn, thisArg) 参数同上。
返回数组中通过函数的第一个元素值,若无返回 undefined
Array.prototype.findIndex(callbackFn, thisArg) 参数同上。
返回数组中通过函数的第一个元素下标,若无返回 -1
Array.prototype.findLast(callbackFn, thisArg) 参数同上。
返回数组中通过函数的最后一个元素值,若无返回 undefined
Array.prototype.findLastIndex(callbackFn, thisArg) 参数同上。
返回数组中通过函数的最后一个元素下标,若无返回 -1
Array.prototype.flat(depth) depth:可选,默认1。要提取嵌套数组的结构深度。Infinity为无限。
返回深度递归将所有子数组元素拼接到新的数组。
Array.prototype.flatMap(callbackFn, thisArg) callbackFn:为数组中的每个元素执行的函数。接收:正在处理的元素、索引和数组本身。三个参数
thisArg:可选,执行时用作 this 的值。
返回每个元素都是回调函数的结果,并且被展开一级的新数组。
Array.prototype.includes(searchElement, fromIndex) searchElement:要查找的值。
fromIndex:可选,开始搜索的索引。
若在数组中找到 searchElement 值,返回true,若否返回false
Array.prototype.indexOf(searchElement, int) int:(可选、转化为整数)开始搜索的索引,默认为0,若超出数组长度直接返回 -1。
返回首个被找到的searchElement元素(区分类型)在数组中的索引位置,若没有找到则返回 -1。
Array.prototype.join(str) str:(可选)来链接数组的每个元素。默认用,分隔。若为空字符串(""),则所有元素之间都没有任何字符。
将元素连接成一个字符串并返回这个字符串。
Array.prototype.keys() 返回一个新的数组迭代器对象,其中包含数组中每个索引的键。
Array.prototype.lastIndexOf(searchElement, int) int:(可选、转化为整数)开始搜索的索引,默认为0,若超出数组长度直接返回 -1。
返回最后被找到的searchElement元素(区分类型)在数组中的索引位置,若没有找到则返回 -1。
Array.prototype.map(callbackFn, thisArg) callbackFn:为数组中的每个元素执行的函数。接收:正在处理的元素、索引和数组本身。三个参数
thisArg:可选,执行时用作 this 的值。
返回每个元素都是回调函数的返回值组成的新数组。
Array.prototype.pop() 删除最后一个元素,并返回被删除的元素,
当数组为空时返回 undefined
Array.prototype.push(元素0, 元素1, /… ,/ 元素N) 元素0~N:添加到数组末尾的元素。
返回添加元素后数组的长度。
Array.prototype.reverse() 反转数组中的元素,并返回同一数组的引用。反转发生在原数组,不会进行复制。
Array.prototype.slice(start, end) start:(可选、转化为整数)提取起始处的索引,默认为0。
end:(可选、转化为整数)提取终止处的索引,会提取到但不包含其的位置。
返回一个含有被提取元素的浅拷贝新数组。
Array.prototype.shift() 删除第一个元素,并返回被删除的元素,
当数组为空时返回 undefined
Array.prototype.sort(fun) fun:(可选)定义排序顺序的函数。返回值应该是一个数字。
其符号表示两个元素的相对顺序:正数表示元素1大于元素2,反之亦然,0表相等。
若省略,元素会被转换为字符串,根据 Unicode 码位值排序。
返回经过排序的原始数组的引用。排序发生在原数组,不会进行复制。
Array.prototype.splice(start, deleteCount, 元素1, 元素2, /…,/ 元素N) start:改变开始的索引。
deleteCount:(可选)一个整数,表示从 start 开始删除的元素数量。
元素0~N:(可选)从 start 开始添加到数组的元素。
返回一个包含了删除的元素的数组。若没有删除任何元素,返回一个空数组。
Array.prototype.toReversed() 返回一个元素顺序相反的新数组。
Array.prototype.toSorted(fun) fun:(可选)定义排序顺序的函数。返回值应该是一个数字。
其符号表示两个元素的相对顺序:正数表示元素1大于元素2,反之亦然,0表相等。
返回一个元素按升序排序的新数组。
Array.prototype.toSpliced(start, deleteCount, 元素1, 元素2, /…,/ 元素N) start:改变开始的索引。
deleteCount:(可选)一个整数,表示从 start 开始删除的元素数量。
元素0~N:(可选)从 start 开始添加到数组的元素。
返回一个包含了删除的元素的新数组。
Array.prototype.unshift(元素0, 元素1, /… ,/ 元素N) 元素0~N:添加到数组开始的元素。
返回添加元素后数组的长度。
Array.prototype.values() 返回迭代器对象,代表数组中每个元素的值。
Array.prototype.with(index, value) index:要修改的数组索引。
value:赋值给索引的值。
返回一个新数组,其中 index 索引处的元素被替换为 value

forEach

forEach() 是数组专用的一种特殊的循环,被ES5引入,其本质是一个数组的实体方法。
除非抛出异常,否则没有办法停止或中断 forEach() 循环,
但使用 return 语句实现类似 continue 关键字的效果,即跳过当次循环。 return 返回的值会被忽略。
forEach() 会跳过空(undefined)的数组元素。在循环前,数组的长度已经被保存,不会访问超出数组初始长度的任何元素。
其使用方法如下:
array.forEach(callbackFn(element, index, arr), thisValue)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// callbackFn(element, index, arr)必需。 数组中每个元素需要调用的函数。
// 其中:
// element 必需。当前元素
// index 可选。当前元素的索引值。
// arr 可选。当前元素所属的数组对象。

// thisValue可选。传递给函数的值一般用 "this" 值。
// 如果这个参数为空, "undefined" 会传递给 "this" 值

// 箭头函数
forEach((element) => { /* … */ })
forEach((element, index) => { /* … */ })
forEach((element, index, array) => { /* … */ })
// 回调函数
forEach(callbackFn)
forEach(callbackFn, thisArg)
// 内联回调函数
forEach(function(element) { /* … */ })
forEach(function(element, index) { /* … */ })
forEach(function(element, index, array){ /* … */ })
forEach(function(element, index, array) { /* … */ }, thisArg)

filter

filter() 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。其返回由 return 关键字组成的数组。
forEach 类似不会对空数组进行检测,不会改变原始数组。
其使用方法如下:
array.filter(function(element,index,arr), thisValue)
thisValue:可选,执行该方法的 this 值。
以下是一个数组去重的例子:

1
2
3
4
5
let arr = [1,2,3,2,3,4];
let arrFilter = arr.filter((ele, index, arr) => {
return arr.indexOf(ele) === index;
})
console.log(arrFilter); // 1234

函数(Function)

定义

使用function定义函数。

1
2
3
function 函数名(参数1,参数2,...,参数N) {
函数体;
}

函数实际上是一个函数对象,而函数名可以视为指向该函数的变量。所以可以这样定义。

1
2
3
let 函数名 = function (参数1,参数2,...,参数N) {
函数体;
};

两种定义完全等价,但第二种方式按照完整语法需要在函数体末尾加一个;,表示赋值语句结束。

调用

调用函数时,按顺序传入参数。
js允许传入任意个参数而不影响调用,传入的参数比定义多或少也没有问题。

1
函数名(参数1,参数2,...,参数N); 

立即执行函数

立即执行函数在定义时就会立即执行。
内部会形成块级作用域。

1
2
3
(function(形参列表){
函数体;
})(实参列表);

箭头函数

箭头函数表达式的语法比传统的函数表达式更简洁,但在语义上有一些差异,在用法上也有一些限制:

  • 箭头函数没有独立的 thisargumentssuper ,且不可被用作方法。
    callapplybind也不会改变其this指向。
  • 箭头函数没有 prototype 属性,不可用作构造函数。
    使用 new 调用它们会引发 TypeError。它们也无法访问 new.target 关键字。
  • 箭头函数不能在其主体中使用 yield,也不能作为生成器函数创建。

由于类体具有 this 上下文,作为字段的箭头函数会关闭类的 this 上下文,箭头函数体中的 this 将正确指向实例。
但,由于其是一个闭包,而不是函数本身的绑定,因此 this 的值不会根据执行上下文而改变。
语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
() => 函数体
单个参数 => 函数体
(单个参数) => 函数体
(参数1, 参数N) => 函数体
() => {
函数体
}
单个参数 => {
函数体
}
(参数1, 参数N) => {
函数体
}

只有一个参数时,才能省略括号。若有多个参数、无参数、默认参数、重组参数或其余参数,则需要在参数列表周围加上括号。
只有直接返回表达式时,才可以省略大括号。若函数体有额外的处理,则大括号与return 是必需的。箭头函数无法猜测函数体返回什么或何时返回。

剩余参数

剩余参数允许将一个不定数量的参数表示为一个数组。
如果函数的最后一个命名参数以...为前缀,则其将成为一个由剩余参数组成的真数组,其的元素中从传递给函数的0theArgs.length实际参数提供。

1
2
3
4
5
function(a, b, ...theArgs) {
}
// 一个去重的例子,二者等价
[...new Set(arr)];
new Array(...new Set(arr))

arguments

arguments只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。其类似Array。
利用arguments,可以获得传入的所有参数。例如这个求和函数。

1
2
3
4
5
6
7
8
// sum(1,2,3,4)
function sum() {
let a = 0;
for (let i = 0; i < arguments.length; i++) {
a += arguments[i];
}
return a;
}

函数方法

Function.prototype.call()

call方法来自Function的原型上。
Function.call(thisArg, ...arg)

  • thisArg:在调用 Function 时要使用的 this 值。若函数不在严格模式下,nullundefined 将被替换为全局对象,并且原始值将被转换为对象。
  • ...arg:可选,函数任意多个的参数。

thisArgFunctionthis调用Function,并返回调用后的结果。

1
2
3
4
5
6
7
8
function greet() {
console.log(this.animal, "的睡眠时间一般在", this.sleepDuration, "之间");
}
const obj = {
animal: "猫",
sleepDuration: "12 到 16 小时",
};
greet.call(obj); // 猫 的睡眠时间一般在 12 到 16 小时 之间

Function.prototype.apply()

apply方法来自Function的原型上。
Function.apply(thisArg, argsArray)

  • thisArg:在调用 Function 时要使用的 this 值。若函数不在严格模式下,nullundefined 将被替换为全局对象,并且原始值将被转换为对象。
  • argsArray:可选,类数组对象,调用时的参数的集合。

thisArgFunctionthis调用Function,并返回调用后的结果。

Function.prototype.bind()

bind方法来自Function的原型上。
Function.prototype.bind(thisArg, ...arg)
参数与call方法相同。
返回thisArgthis值,...arg为初始参数的给定函数的副本。

闭包

函数在调用时,内部使用到自身作用域以外的变量,会保留使用到的变量,即使其作用域已经结束。这种特性称为闭包。
闭包可以用作操作私有变量。这些变量不会被外部随意修改,仅可以通过指定的接口来操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function coolModule() {
//私有的数据
var msg = "bdqn";
var names = ["I", "Love", "you"];
//私有的操作数据的函数
function doSomething() {
console.log(msg.toUpperCase());
}
function doOtherthing() {
console.log(names.join(" "));
}
//向外暴露包含多个方法的对象
return {
doSomething: doSomething,
doOtherthing: doOtherthing,
};
}

var myModule=coolModule();
// 操作私有变量
myModule.doSomething();
myModule.doOtherthing();

监听事件、定时器、Ajax请求、跨窗口通信等异步或同步任务中,只要使用回调函数就是闭包。
闭包会携带比其他函数占用更多的内存。可能会导致内存占用过多。
可以使对应的闭包为null来让系统释放资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function fun1() {
var a = 3;
function fun2() {
a++;
console.log(a);
}
return fun2;
}
var f = fun1();
f();
/*
......
*/
// 使用完后将对象置空来释放。
f = null;

Math

Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。其用于 Number 类型,不支持 BigInt
与其他全局对象不同的是,Math 不是一个构造器。Math 的所有属性与方法都是静态的。
以下是其静态属性与方法:

属性/方法 介绍
Math.E 返回算术常量 e,即自然对数的底数(约等于2.718)。
Math.LN2 返回 2 的自然对数(约等于0.693)。
Math.LN10 返回 10 的自然对数(约等于2.302)。
Math.LOG2E 返回以 2 为底的 e 的对数(约等于 1.4426950408889634)。
Math.LOG10E 返回以 10 为底的 e 的对数(约等于0.434)。
Math.PI 返回圆周率(约等于3.14159)。
Math.SQRT1_2 返回 2 的平方根的倒数(约等于 0.707)。
Math.SQRT2 返回 2 的平方根(约等于 1.414)。
Math.abs(num) 返回 num 的绝对值。
math.acos(num) 返回 num 的反余弦值。
math.asin(num) 返回 num 的反正弦值。
math.atan(num) 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 num 的反正切值。
math.atan2(y,x) 返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。
math.ceil(num) 对数进行上舍入。
Math.cos(num) 返回数的余弦。
Math.exp(num) 返回 E num 的指数。
Math.floor(num) num 进行下舍入。
Math.log(num) 返回数的自然对数(底为e)。
Math.max(num1,num2,…,numn) 返回 num1,num2,…,numn 中的最高值。
Math.min(num1,num2,…,numn) 返回 num1,num2,…,numn 中的最低值。
Math.pow(num1,num2) 返回 num1num2 次幂。
Math.random() 返回 0 ~ 1 之间的随机数。
*x 后可以生成一个0~x之间的随机数。
*(y-x)+x 后生成一个x~y之间的随机数。
Math.round(num) 四舍五入。
Math.sin(num) 返回数的正弦。
Math.sqrt(num) 返回数的平方根。
Math.tan(num) 返回角的正切。
Math.tanh(num) 返回一个数的双曲正切函数值。
Math.trunc(num) 将数字的小数部分去掉,只保留整数部分。

Date

Date 表示时间中的某个时刻,存储方式是1970年1月1日(UTC)起经过的毫秒数。
以下是其构造函数的重载:

重载 介绍
new Date() 返回一个表示现在时间的Date对象
new Date(milliseconds) milliseconds: 时间戳,表示自1970年1月1日00:00:00以来的毫秒数。
返回milliseconds所表示时间的Date对象。
new Date(dateString) dateString:指定日期和时间的字符串。
返回dateString所表示时间的Date对象。
new Date(year, month, day, hours, minutes, seconds, milliseconds) 分别表示年、月、日、时、分、秒、毫秒。可以省略较详细的参数。
返回参数所表示时间的Date对象。
Date() 返回表示当前时间的字符串,类似new Date().toString()
Date.now() 获取当前代码执行时的时间的时间戳。

以下是一些常用方法:

方法 介绍
Date.getFullYear() 返回Date的年份。
Date.getMonth() 返回Date的月份,月份范围是0~11
Date.getDate() 返回Date的日期。
Date.getDay() 返回Date的星期,0表示周日、7表示周六。
Date.getHours() 返回Date的小时,24小时制。
Date.getMinutes() 返回Date的分钟。
Date.getSeconds() 返回Date的秒。
Date.getMilliseconds() 返回Date的毫秒数。
Date.getTime() 返回Date的时间戳,以number形式表示。

Map

Map是一组键值对的结构,无论这个结构有多大,查找速度都为N(1)。
初始化Map用二维数组,或者直接初始化一个空Map
使用gat进行查询,set添加会覆盖之前的值,has判断是否存在,delete删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

let m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
m.set('Adam', 88);
m.get('Adam'); // 88
m.size; // 获取长度 1
m.clear(); // 清除所有元素
m.size; // 0

实例属性/方法

属性/方法 介绍
Map.prototype.size 键值对的数量。
Map.prototype.clear() 移除所有的键值对。
Map.prototype.delete(key) key:键。
移除键为 key 的键值对,若成功返回 true,否则返回 false。
Map.prototype.entries() 返回迭代器,其包含所有键值对,以插入顺序排列。
Map.prototype.get(key) key:键。
返回与指定键的关联值,若不存在返回 undefined
Map.prototype.has(key) key:键。
判断否存在与指定键的关联值。
Map.prototype.keys() 返回迭代器,其包含所有元素的键,以插入顺序排列。
Map.prototype.set(key, value) 添加指定的键值对。
Map.prototype.values() 返回迭代器,其中包含所有值,以插入顺序排列。

Set

SetMap类似,也是一组key的集合,但不存储value,且没有重复的key
创建Set,需要Array,或创建一个空Set
重复元素在Set中自动被过滤。

迭代器

迭代器是一个对象,其定义一个序列,并在终止时可能附带一个返回值。
要判断一个对象是不是可迭代的,看其是否存在 [Symbol.iterator]() 方法。该方法返回的就是迭代对象。
其中包含:

  • next()方法:将迭代器指向下一个位置,并返回一个迭代结果对象,其中包含:
    • done:默认为false,是否迭代完毕。
    • value:默认为undefined,值。

若想使迭代器也迭代,只需实现 [Symbol.iterator]() 方法,并返回迭代器自身的 this

生成器

生成器允许自定义定义一个非连续执行的函数作为迭代算法。无需自行编写 next() 方法。
定义一个生成器方法需在方法前加上 * 声明其为生成器方法。
调用生成器函数不会执行实际的函数体,而是返回一个生成器对象,其也是迭代器对象。
当这个对象调用 next() 方法时会运行生成器的函数体,直到 yield 给出返回值。
next()方法也可以接受参数,传递给上条 yield 语句。
在生成器中, return 与最后条 yield 效果一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function* builder() {
// a 丢失了
let a1 = yield 1;
console.log(a1); // b
let a2 = yield 2;
console.log(a2); // c
let a3 = yield 3;
console.log(a3); // d
let a4 = yield 4;
console.log(a4); // e
return 5;
}
let b1 = builder();
console.log(b1.next("a")); // { value: 1, done: false }
console.log(b1.next("b")); // { value: 2, done: false }
console.log(b1.next("c")); // { value: 3, done: false }
console.log(b1.next("d")); // { value: 4, done: false }
console.log(b1.next("e")); // { value: 5, done: true }

BOM(Window)

BOM(browser Object)浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 Window

Window.document

Window.document只读属性,获取 Document 对象,也就是 DOM

Document.cookie可以获取/设置与当前文档相关联的 cookie
cookie以键值对的方式存储值。
key1=value1;key2=value2;...keyN=valueN
以下可以跟在键值对后,用来对 cookie 的设定/更新:

  • ;path=path:路径,默认为当前文档位置的路径。
  • ;domain=domain:域名,默认为当前文档位置的路径的域名部分。
  • ;max-age=max-age-in-seconds:访问后的存活时间,相对文档的请求时间。单位为秒。
  • ;expires=date-in-GMTString-format:绝对的过期时间,相对文件的最后访问时间。若没有定义,在对话结束时过期。Date对象。
  • ;secure:只通过 https 协议传输。

Window.sessionStorage

Window.sessionStorage获取对应当前源短期的 Storage 对象。
打开多个相同的 URL 的页面,会创建各自的 sessionStorage。关闭对应浏览器标签或窗口,会清除对应的 sessionStorage
Storage 对象同样以键值对的方式存储值。
Storage 对象常用属性如下:

属性 介绍
Storage.length 只读,返回存储在 Storage 对象中的数据项数量。

常用方法如下:

方法 介绍
Storage.key(n) 返回存储中的第 n 个键名。
Storage.getItem(key) 返回key对应的值。
Storage.setItem(key,value) keyvalue以键值对添加到存储中,若key存在,则更新对应的value
Storage.removeItem(key) key从存储中删除。
Storage.clear() 清空存储中的所有数据。

Window.localStorage

Window.localStorage获取对应当前源长期的 Storage 对象。
打开多个相同的 URL 的页面,共用 localStorage。除非手动清除数据,否则数据不会清除。

Window.location

Window.location 只读属性,获取 Location 对象,表示有关文档URL相关的信息。
其常用属性如下:

属性 介绍
Location.href 返回当前加载页面的完整URL
Location.hash 返回URL# 和之后的 URL 片段标识符。
Location.host 返回服务器名称和端口号。
Location.hostname 返回不带端口号的服务器名称。
Location.pathname 返回URL中的目录和文件名。
Location.port 返回URL中指定的端口号。
Location.protocal 返回页面使用的协议。
Location.search 返回URL的查询字符串,包含 ? 以及其后的URL查询参数。

常用方法如下:

方法 介绍
Location.assign(url) url:字符串,要跳转到的链接。
若由于安全原因无法跳转,会抛出 SECURITY_ERROR 错误。
url无效,抛出 SYNTAX_ERROR 错误。
Location.replace(url) url:字符串,要跳转到的链接。
assign()不同,页面不会保存到会话历史中
若由于安全原因无法跳转,会抛出 SECURITY_ERROR 错误。
url无效,抛出 SYNTAX_ERROR 错误。
Location.reload() 刷新当前页面。

Window.navigator

Window.navigator 只读属性,获取Navigator 对象,用于请求用户代理的状态和身份。
基本只使用Navigator.userAgent属性表示浏览器类型。
可以使用/Chrome/i/firefox/i/msie/i来判断浏览器类型。
用户代理字符串是可以由用户配置的。所以基于用户代理字符串来识别浏览器是不可靠不推荐

Window.history

Window.history只读属性,获取 History 对象,提供了操作浏览器会话历史。
其常用属性如下:

属性 介绍
History.length 当前访问的网页的链接数量会话历史中元素的数目,包括当前加载的页。

常用方法如下:

方法 介绍
History.back() 回退到上一个页面。
History.forward() 前进到下一个页面。
History.go(delta) delta:可选相对于当前页面你要去往历史页面的位置。负值表示向后移动,正值表示向前移动。
若未传参或为 0,则刷新当前页面。

Window.screen

Window.screen只读属性,获取 screen 对象。当前渲染窗口中和屏幕有关的属性。
其常用属性如下:

属性 介绍
Screen.width 屏幕的宽度分辩率。
Screen.height 屏幕的高度分辩率。

弹框方法

方法 介绍
Window.alert(message) message:可选,显示在警告对话框中的字符串。
Window.confirm(message) message:可选,在确认对话框中要显示的字符串。
返回用户是否确定。
Window.prompt(message, defaultValue) message:可选,在提示对话框中要显示的字符串。
defaultValue:提示对话框中显示的默认值。
返回用户输入的文本。

记时器方法

Window.setTimeout

Window.setTimeout()设置一个定时器,定时器归零后执行一次给定的操作。
Window.setTimeout(functionRef, delay, …paramN)

  • functionRef:当定时器归零后要执行的函数。
  • delay:可选,定时器等待时间,单位为毫秒。
    若省略则立即执行。
  • …paramN:会传递给 functionRef 的附加参数。
    返回 timeoutID:正整数,创建定时器的唯一标识符。

Window.clearTimeout()取消通过调用 Window.setTimeout() 建立的任务。
Window.clearTimeout(timeoutID)

  • timeoutID:要取消定时器的标识符。

Window.setInterval

Window.setInterval()设置一个定时器,定时器归零后执行一次给定的操作,再重新计时循环执行。
Window.setInterval(functionRef, delay, …paramN)

  • functionRef:当定时器归零后要执行的函数。
  • delay:可选,定时器等待时间,单位为毫秒。
    若省略则默认为4。
  • …paramN:会传递给 functionRef 的附加参数。
    返回 timeoutID:正整数,创建定时器的唯一标识符。

Window.clearInterval()取消通过调用 Window.setInterval() 建立的任务。
Window.clearInterval(timeoutID)

  • timeoutID:要取消定时器的标识符。

异步

在JS中属于异步的有:

  • 定时器:setTimeout、setInterval。
  • 网络请求:ajax请求、动态创建img标签的加载。
  • 事件监听器:addEventListener。
  • 异步对象:Promise。

期约(Promise)

期约Promise 其为一个代表了异步操作的最终完成或者失败的对象。
一个 Promise 必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败。

构造函数

其主要用于封装尚未支持 Promise 的基于回调的 API
new Promise(executor)

  • executor:在构造函数中执行的 function。其中抛出的任何错误都会导致 Promise 被拒绝,并且返回值将被忽略。其可以接收两个函数作为参数:
    resolveFunc:兑现期约处理函数。
    rejectFunc:拒绝期约处理函数。

返回一个 Promise 对象。当 resolveFunc 或者 rejectFunc 被调用时,该 Promise 对象就会变为已解决(resolved)。

静态属性/方法

属性/方法 介绍
Promise.all(iterable) iterablePromise 可迭代对象。
返回 Promise其在所有输入的 Promise 都兑现时被兑现,其值为一个包含所有兑现值的数组。
若输入的任何 Promise 被拒绝,返回的 Promise 也会被拒绝,并返回第一个拒绝的原因。
Promise.allSettled(iterable) iterablePromise 可迭代对象。
返回 Promise,其在所有输入的 Promise 都敲定时兑现。
其值为一个描述每个 Promise 结果的对象数组,每个对象包含:
status:字符串,”fulfilled”或”rejected”,表示 promise 的最终状态。
value:当 status 为 “fulfilled”时存在。promise 兑现的值。
reason:仅当 status 为 “rejected” 时存在,promsie 拒绝的原因。
Promise.any(iterable) iterablePromise 可迭代对象。
返回 Promise,在任何输入的 Promise 兑现时兑现,其值为第一个兑现的值。
若所有输入的 Promise 都被拒绝,返回的 Promise 将以带有一个包含拒绝原因的数组 AggregateError
Promise.race(iterable) iterablePromise 可迭代对象。
返回 Promise,与第一个敲定 Promise 的最终状态保持一致。
Promise.reject(reason) reasonPromise 对象被拒绝的原因。
返回新 Promise 对象,以给定的原因拒绝。
Promise.resolve(value) valuePromise 对象 resolveFunc 函数的参数。。
返回新 Promise 对象,该对象以给定的值兑现。
若值是一个 thenable 对象(即具有 then 方法),会“跟随”该 thenable 对象,采用其最终的状态。
该方法可以将 value 转换成 Promise 对象。

实例属性/方法

属性/方法 介绍
Promise.prototype.catch(onRejected) onRejected:此 Promise 对象被拒绝时异步执行的函数。其返回值将成为 catch() 返回的 Promise 对象的兑现值。该回调函数被调用时将传入一个参数,表 Promise 的拒绝值。
返回新 Promise,该对象在返回时处于待定(pending)状态。
onRejected 被调用了,新返回的 promise 将根据此调用的返回值进行兑现,或者使用此调用引发的错误进行拒绝。
若当前 promise 已兑现,则 onRejected 不会被调用,且返回的 promise 具有相同的兑现值。
Promise.prototype.finally(onFinally) onFinally:当 promise 被敲定时异步执行的函数。其除非返回一个被拒绝的 promise 否则返回值将被忽略。无参数。
返回新 Promise,该对象在返回时处于待定(pending)状态。
onFinally 抛出错误或返回被拒绝的 promise时新 promise 将使用该值进行拒绝。
否则,新 promise 将以与当前 promise 相同的状态敲定(settled)。
Promise.prototype.then(onFulfilled, onRejected) onFulfilled:可选,在 Promise 对象被兑现时异步执行的函数。其返回值将成为 then() 返回新 Promise 对象的兑现值。此函数被调用时将传入 Promise 对象的兑现值。
onRejected:可选,在 Promise 对象被拒绝时异步执行的函数。其返回值将成为 catch() 返回新 Promise 对象的兑现值。此函数被调用时将传入 Promise 对象被拒绝的原因。
返回新 Promise 对象,该对象在返回时处于待定(pending)状态。
onFulfilledonRejected 处理函数之一将被执行,以处理当前 Promise 对象的兑现或拒绝。即使当前 Promise 对象已经敲定,这个调用也总是异步发生的。

优势

Promise 常用于异步操作函数返回的对象,可以在其之上绑定回调函数,这样无需在一开始把回调函数作为参数传入这个函数。
如果连续执行多个异步操作,且在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。这种操作会导致多层函数嵌套,称为 回调地狱 。如下:

1
2
3
4
5
6
7
doSomething(function (result) {
doSomethingElse(result, function (newResult) {
doThirdThing(newResult, function (finalResult) {
console.log(`得到最终结果:${finalResult}`);
}, failureCallback);
}, failureCallback);
}, failureCallback);

Promisethen() 函数会返回一个和原来不同的新的 Promise
这样就可以使用多个链式 then() 来完成上面的操作。这样的操作称为 期约链

1
2
3
4
const promsie = doSomething();
promise
.then(doSomethingElse)
.then(doThirdThing);

async/await

期约Promise 的使用虽然通过期约链大大简化了嵌套异步调用。但依然较为复杂。
async/await 基于期约,大大的简化了期约的复杂性,使得异步代码可以像带有阻塞的同步代码一样便于理解。

async

async 关键字只能用于函数前(包括箭头函数)。只有在设置为 async 函数中可以使用 await 关键字。
被声明为 async 的函数默认返回一个 期约Promise 对象,若函数显示声明了返回值这个返回值会被认为是该期约敲定后的兑现值或拒绝值。

await

只有在设置为 async 函数中可以使用 await 关键字。
await 关键字用于 期约Promise 对象前。
该关键字将阻塞其之后的代码,直到其所声明的 期约Promise 对象被敲定。该关键字将返回敲定后的兑现值或拒绝值。并运行其之后的代码。

例子

一个从url获取response,再从response获取json的例子。
await 将等待 fetch() 落定再执行之后的代码。

1
2
3
4
5
6
7
8
async function getJSON(url) {
// fetch返回一个期约对象,从url读取响应。
const response = await fetch(url);
// 等待前条 await 语句返回才继续执行。
const json = await response.json();
// 将作为该函返回数期约的敲定值。
return json;
}

若不必顺序执行的代码可以使用 Promise.all() 来并发执行。

1
2
3
4
5
6
7
8
async (url) => {
let [value1,value2] =
await Promise.all([
getJSON(url[0]),
getJSON(url[1])
]);
return [value1,value2];
}

module

模块化(module),是复杂的项目需要一种将程序拆分为可按需导入的单独模块的机制。

导出模块

为了获得模块的功能,首先使用export语句将其导出。
export放至要导出项的前面。

1
2
3
4
5
export const name = "name";

export function fun() {
return 123;
}

export须置于外层,无法在函数中使用。
批量导出时,在模块文件末尾使用一个 export 语句,用花括号与逗号分隔的形式列出所有需导出的对象。
在对象列表中可以使用as关键字来重命名。

1
export { className as name, age, obj, fun };

使用export default关键字来设置默认导出。
默认导出一个文件只能存在一个。

1
export default Obj;

导入模块

使用 import 语句、对象列表、 from 关键字、地址。来导入模块。
对象列表可以使用通配符*引入所有对象。
在对象列表中可以使用as关键字来重命名。
在对象列表中可以使用default来获取默认导出。

1
2
3
import { name as newName , age, obj, fun } from "./module文件.js";
import * from "./module文件.js";
import { default as randomSquare } from "./module文件.js";

或使用script标签以module类型引入。

1
<script src="./module文件.js" type="module"></script>

网络

js 原生的网络请求有

  • XMLHttpRequest:基于回掉实现的异步请求。
  • FetchAPI:基于期约实现的异步请求,更加现代和简洁。

除此之外还有基于 XMLHttpRequest 使用期约重新封装的 AxiosAPI

XMLHttpRequest

XMLHttpRequest 使用回调来实现异步网络请求。
使用构造函数 XMLHttpRequest() 来实例化一个 XMLHttpRequest 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getData(url,callbackFun) {
let xhr = new XMLHttpRequest();
xhr.addEventListener("load", callbackFun);
xhr.open("GET", url);
xhr.send();
}

function postData(url,body,callbackFun) {
let xhr = new XMLHttpRequest();
xhr.addEventListener("load", callbackFun);
xhr.open('POST', url);
// 设置 Content-Type属性(固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(body);
}

实例属性/方法

介绍
XMLHttpRequest.onreadystatechange readyState 属性发生变化时,触发的回调函数。
相当于为 readystatechange 事件设置监听函数。
XMLHttpRequest.readyState 只读,返回请求的状态码。
XMLHttpRequest.response 只读,返回响应正文,其类型取决于该对象的 responseType 属性值。
XMLHttpRequest.responseText 只读,返回请求响应的字符串,若请求未成功或尚未发送回 null
XMLHttpRequest.responseType 一个枚举字符串值,用于指定响应中包含的数据类型。包含:
“”:与默认类型 “text” 相同。
“arraybuffer”:包含二进制数据的 ArrayBuffer 类型。
“blob”:包含二进制数据的 Blob 对象。
“document”:是一个 HTML Document 或 XML XMLDocument类型。
“json”:将接收到的数据内容解析为 JSON 而创建的 JavaScript 对象。
“text”:的文本。
“ms-stream”:非标准,流式下载的一部分,仅允许用于下载请求。
XMLHttpRequest.responseURL 只读,返回经过序列化的响应 URL
XMLHttpRequest.responseXML 只读,返回一个包含请求检索的 HTML 或 XML 的Document,若无法解析返回null
XMLHttpRequest.status 只读,响应状态。
XMLHttpRequest.statusText 只读,返回完整响应状态文本,如”200 OK”。
XMLHttpRequest.timeout 表该请求的最大请求时间毫秒,若超出该时间,请求会自动终止。
XMLHttpRequest.upload 只读,XMLHttpRequestUpload 类型,表上传进度。
XMLHttpRequest.withCredentials 指定跨域 Access-Control 请求是否应当带有授权信息,如 cookie 或授权 header 头。
XMLHttpRequest.abort() 若请求已发出,则立刻中止请求。
XMLHttpRequest.getAllResponseHeaders() 以字符串的形式返回所有用\r\n分隔的响应头,若没有收到响应返回 null
XMLHttpRequest.getResponseHeader(name) name:报文项名称。
返回name对应的字符串,若不存在返回 null
XMLHttpRequest.open(method, url, async, user, password) method:要使用的 HTTP 方法,如 GETPOSTPUTDELETE…。
url:字符串表示要向其发送请求的 URL
async: 可选,默认 true。是否异步执行操作。
user: 可选,默认 null。用于认证用途的用户名。
password:可选,默认 null。用于认证用途的密码。
初始化一个请求。
XMLHttpRequest.overrideMimeType(mimeType) mimeType:字符串,表 MIME 类型
覆写由服务器返回数据为指定的 MIME 类型。
XMLHttpRequest.send(body) body:可选,发送请求的数据体。
发送请求。
XMLHttpRequest.setRequestHeader(header, value) header:标头名称。
value:标头对应的值。
设置 HTTP 请求标头的值。必须在 open() 之后、send() 之前调用此方法。

事件

介绍
abort 当请求终止时触发。
error 当请求错误时触发。
load 当请求成功完成时触发。
loadend 当请求结束时触发,无论请求成功 load , 还是失败 aborterror
loadstart 接收到响应数据时触发。
progress 当请求接收到更多数据时,周期性地触发。
timeout 在预设时间内没有接收到响应时触发。

FetchAPI

FetchAPI 提供了一些获取资源的接口,如RequestResponse 等对象的通用定义与 Window.fetch()这样发起获取资源请求的方法。

Fetch

Window.fetch(resource, options)

  • resource:要获取的资源。其可以是:
    • 字符串,要获取的资源的 URL。
    • Request 对象。
  • options: 可选,RequestInit 对象。

返回一个 Promise,兑现 Response 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
async function getJSON() {
try {
let response = await fetch(url);
if (response.status >= 200 && response.status < 300) {
return await response.json();
} else {
throw new Error(response.statusText);
}
} catch (error) {
console.log('Request Failed', error);
}
}

async function postData() {
const response = await fetch(url, {
method: 'POST',
headers: {

},
body: '.....',
});
const json = await response.json();
}

Headers

Fetch APIHeaders 接口允许对 HTTP 请求和响应头执行各种操作。
使用构造函数 Headers(init) 来实例化一个 Headers 对象。其中:

  • init:可选,包含任意 HTTP标头 的对象。
实例方法
介绍
Headers.append(name, value) nameHTTP标头 名称。
valueHTTP标头 值。
添加对应的 HTTP标头 与值。
Headers.delete(name) nameHTTP标头 名称。
删除指定标头。
Headers.entries() 以 迭代器 的形式返回该对象中所有的键值对。
Headers.get(name) nameHTTP标头 名称。
检索到的标头的值,如果未设置该标头为 null。
Headers.has(name) nameHTTP标头 名称。
否存在指定的标头。
Headers.keys() 以迭代器的形式返回该对象中所有标头名。
Headers.set(name, value) nameHTTP标头 名称。
valueHTTP标头 值。
替换或添加对应 HTTP标头 的值。
Headers.values() 以迭代器的形式返回该对象中所有标头的值。

Request

Fetch APIRequest 接口用来表示资源请求。
使用构造函数 Request(input, options) 来实例化一个 Request 对象。其中:

  • input:URL。
  • options:可选,请求中的各种自定义选项。可用的选项如下:
    • method: 请求的方法,如 GET, POST。
    • headers: 请求头。
    • body: 请求体。
    • mode: 请求模式,默认值为 cors。
    • credentials: 请求凭证,默认值为 include。
    • cache: 缓存模式。
    • redirect: 重定向模式,默认值为 follow。
    • referrer:反向链接。
    • integrity: 子资源完整性。
实例方法/属性
介绍
Request.body 只读,ReadableStream 对象包含已添加到请求中的主体内容。
Request.bodyUsed 只读,请求体是否已经被读取。
Request.cache 只读,请求的缓存模式 可能的值
Request.credentials 只读,请求凭据,默认为 same-origin。
可能的值:
omit: 从不发送 cookies。
same-origin: 只有当 URL 与响应脚本同源才发送 cookies、HTTP Basic authentication 等验证信息。
include: 不论是不是跨域的请求,总是发送请求资源域在本地的 cookies、HTTP Basic authentication 等验证信息。
Request.destination 只读,描述请求的内容类型的字符串。可能的值
Request.headers 只读,请求相关联的 Headers 对象。
Request.integrity 只读,请求的子资源完整性值
Request.method 只读,请求的方式(GET、POST 等)。
Request.mode 只读,请求的模式。
可能的值:
same-origin:确保请求总是向当前的源发起的。
no-cors:保证请求被 ServiceWorker 劫持后除了 simple header ,不能添加或修改其他 header。
cors:允许跨域请求。
navigate:页面切换请求。
Request.redirect 只读,处理重定向的模式。可能是 follow、error 或 manual 之一。
Request.referrer 只读,反向链接。
Request.signal 只读,请求相关联的 AbortSignal对象。
Request.url 只读,请求的 URL。
Request.arrayBuffer() 返回 promise,其兑现值为请求主体的二进制数据 ArrayBuffer
Request.blob() 返回 promise,其兑现值为请求主体的 Blob
Request.clone() 创建当前 Request 对象的副本。
Request.formData() 返回 promise,其兑现值为请求主体的键值对 FormData
Request.json() 返回 promise,其兑现值为请求主体经过 JSON 解析的结果。
Request.text() 返回 promise,其兑现值为请求主体的文本表示形式。

Response

Fetch APIResponse 接口表示请求的响应数据。
使用构造函数 Response(body, init) 来实例化一个 Response 对象。其中:

  • body:可选,相应主体。
  • init:可选,状态消息。可用的选项如下:
    • status: response 的状态码,如:200。
    • statusText: 和状态码关联的状态消息,如:OK。
实例方法/属性
介绍
Response.body 只读,响应数据主体。
Response.bodyUsed 只读, body 是否被使用过。
Response.headers 只读,响应数据的Headers对象。
Response.ok 只读,表明响应是否成功(状态码在 200~299 范围内)。
Response.redirected 只读,是否来自重定向的请求。
Response.status 只读,响应的状态码。
Response.statusText 只读,响应的状态文本。
Response.type 只读,响应的类型。
可能的值:
basic:标准值,同源响应,暴露除了Set-Cookie之外的所有标头。
cors:从有效的跨源请求接收到响应。
error:网络错误。
opaque:对跨源资源的 no-cors 请求的响应。
opaqueredirect:响应的状态是 0,标头是空的,主体是 null。
Response.url 只读,url。
Response.arrayBuffer() 返回 promise ,其其兑现值为一个ArrayBuffer对象。
Response.blob() 返回 promise,其兑现值为请求主体的 Blob
Response.clone() 创建当前 Response 对象的副本。
Response.formData() 返回一个 Promise ,其兑现值为一个FormData对象,其值为读取的数据流。
Request.json() 返回 promise,其兑现值为请求主体经过 JSON 解析的结果。
Request.text() 返回 promise,其兑现值为请求主体的文本表示形式。

其他

parseInt

parseInt(string, radix)
string:要被解析的值。如果参数不是一个字符串,则使用 ToString 将其转换为字符串。
radix:可选,默认10。表示进制。只接受从 2 到 36 的整数。
解析 string 并返回指定基数的十进制整数。当 radix 小于 2 或大于 36,或第一个非空格字符不能转换为数字时返回 NaN

严格模式

除了正常运行模式,ECMAscript 5添加了第二种运行模式:”严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
设立”严格模式”的目的,主要有以下几个:

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。
  • 消除代码运行的一些不安全之处,保证代码运行的安全。
  • 提高编译器效率,增加运行速度。
  • 为未来新版本的Javascript做好铺垫。

"use strict"放在脚本文件的第一行,则整个脚本都将以”严格模式”运行。如果这行语句不在第一行,则无效。

1
2
3
4
<script>
    "use strict";
    console.log("这是严格模式。");
  </script>

"use strict"放在函数体的第一行,则整个函数以”严格模式”运行。

1
2
3
4
function strict(){
    "use strict";
    return "这是严格模式。";
  }

class中将自动启用严格模式。
严格模式对语法和行为,做了一些改变:

  1. 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。
  2. 禁止this关键字指向全局对象。
  3. 无法删除变量。只有configurable设置为true的对象属性,才能被删除。
  4. 对象不能有重名的属性、函数不能有重名的参数。
  5. 不允许在非函数的代码块内声明函数。

正则表达式

正则表达式RegExp是用于匹配字符串中字符组合的模式。
其可以作为参数使用 StringmatchmatchAllreplacesearchsplit 方法。
其还拥有以下实例方法:

实例方法 介绍
regex.test(str) str:要匹配正则表达式的字符串。
正则与str匹配返回true,否则返回false
regex.exec(str) str:要匹配正则表达式的字符串。
匹配失败返回 null,并将RegExplastIndex 属性置为 0。若成功返回一个数组,并更新RegExplastIndex 属性。再次查找同一str时,将会在上次找到的之后查找。
匹配成功的文本将作为返回数组的第一项。数组拥有两个属性
index:匹配字符的索引。
input:匹配的原始字符串。
1
2
3
4
5
6
7
8
const regex1 = /foo*/g;
const str1 = 'table football, foosball';
let array1;
while ((array1 = regex1.exec(str1)) !== null) {
console.log(array1[0]); // foo foo
console.log(array1.index); // 6 16
console.log(array1.input); // table football, foosball table football, foosball
}

JSON

JSON 是一种按照 JavaScript 对象语法的数据格式。独立于 JavaScript。实践证明其是一种非常通用的数据格式,许多其他语言都对其支持。
其可以被储存在文件中,基本上就是一个文本文件,扩展名为 .json
JavaScript 中可以通过JSON.stringify()JSON.parse()实现对象和文本间的相互转换。

JSON.stringify

该方法可以将一个 JavaScript 对象或值转换为 JSON 字符串。
JSON.stringify(value, replacer , space)

  • value:将要序列化成 JSON 字符串的对象。
  • replacer:可选,
    若为函数,则在序列化过程中,每个值的每个属性都会经过该函数的转换和处理;
    若为数组,则只会序列化数组中的属性名。
  • space:可选,指定缩进用的空格,上限为 10。

返回转换完成的 JSON 字符串。
若在序列中遇到原生 JSON 不支持的类型,会尝试调用其toJSON()代替原始值。

JSON.parse

该方法用于解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。
JSON.parse(text, reviver)

  • text:要解析成 JavaScript 值的字符串。
  • reviver: 可选,函数类型,用于修改解析生成的原始值。其可以接收到keyvalue用于判断。

返回与给定 text 相对应的值。

交叉观察器

交叉观察器 IntersectionObserver 提供了异步检测目标元素与祖先元素或顶级文档的视口相交情况变化的方法。

构造方法

IntersectionObserver(callback, options)

  • callback:当元素可见比例超过阈值后,调用的回调函数,此回调函数可以接受两个参数:
    entries:一个 IntersectionObserverEntry 类型的数组,包含每个被触发的阈值对象。
    observer:触发阈值的IntersectionObserver实例本身。
  • options:可选,用于配置参数的实例对象。若未指定,默认使用文档视口作为 root,没有 margin,阈值为 0%。其可以指定以下配置:
    root:监听元素的祖先元素Element对象,其边界盒将被视作视口。
    rootMargin:计算交叉值的一组偏移量, string 类型 ,默认值是”0px 0px 0px 0px”。
    threshold:对象触发阈值的数组,参数在1~0之间。

实例属性

属性 介绍
IntersectionObserver.root 只读,用作边界盒的元素。若造函数未传入 root 默认使用顶级文档的视口。
IntersectionObserver.rootMargin 只读,计算交叉时添加到根边界盒的矩形偏移量,默认值为“0px 0px 0px 0px”。
IntersectionObserver.thresholds 只读,对象触发阈值的数组。如果构造器未传入值,则默认值为 0。

实例方法

方法 介绍
IntersectionObserver.disconnect() 停止监听所有该对象的目标。
IntersectionObserver.observe(targetElement) targetElement:要监视其在根范围内的可见性的元素。此元素必须是根元素的后代。
targetElement添加到该对象的监听列表。
IntersectionObserver.takeRecords() 返回IntersectionObserverEntry 对象数组,每个对象包含目标元素自上次相交检查以来与根的相交状态变化。
IntersectionObserver.unobserve(target) target:要取消监听的目标,若未提供,不做任何事情、不抛出异常。

IntersectionObserverEntry

IntersectionObserverEntry 描述了目标元素与其根元素容器在某一特定过渡时刻的交叉状态。
其拥有一些属性如下:

属性 介绍
IntersectionObserverEntry.boundingClientRect 只读,返回包含目标元素的边界信息的DOMRectReadOnly,计算方式与 Element.getBoundingClientRect() 相同。
IntersectionObserverEntry.intersectionRatio 只读,返回元素显示的比例值。
IntersectionObserverEntry.intersectionRect 只读,返回一个 DOMRectReadOnly 用来描述根和目标元素的相交区域。
IntersectionObserverEntry.isIntersecting 只读,返回一个布尔值,表示监听元素是否在根元素上可见。
IntersectionObserverEntry.rootBounds 只读,返回一个 DOMRectReadOnly 描述交叉区域观察者中的根。
IntersectionObserverEntry.target 只读,与根出现相交区域改变的元素。
IntersectionObserverEntry.time 只读,返回一个记录从 IntersectionObserver 的时间原点到交叉被触发的时间的时间戳。

参考资料

面向开发者的 web 技术 JavaScript 文档
JavaScript权威指南 (原书第7版)
廖雪峰的 JavaScript 教程
菜鸟 JavaScript 教程
Axios 中文文档
JavaScript单例模式的三种实现
彻底搞懂JS原型与原型链
原型链是什么?20分钟带你走进js的世界。

关于本人

HaiYao的博客
Git主页

评论