Time-Traveler

时光旅人,向往美好

0%

01-let和const

01-共同特点

01-块级作用域

02-没有声明提升

03-不允许重复声明

02-const特有特点

01-声明不可变常量

02-不可变只针对简单的常量,复合常量只是表示指向的地址值不会变,但是内部的属性无法控制不变(const声明的对象和数组可以在后续进行相应的修改)

02-变量的解构

01-数组解构(按照顺序)

1
let [a, b, c] = [1, 2, 3];

02-对象解构(按照属性名)

1
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };

03-默认值

1
2
let [a, b, c = 3] = [1, 2];
c //3

可以用于解构嵌套变量(如套娃json对象)

04-函数参数的结构赋值

按照传入参数的类型自行解构,解构失败使用默认值

05-圆括号慎用

等用到回来查

03-字符串扩展

01-for…of…遍历字符串内的每一个字符

02-unicode支持

03-模板语法

1
`/*模板内容*/`

可能会涉及<%%>转换问题,可以提前使用正则表达式解决

04-字符串新增方法

01-String.fromCodePoint()

正确返回Unicode码点对应的字符

02-String.raw()

生成一个把单斜杠变成双斜杠的字符换,常用语模板语法

03-codePointAt()

获得字符串某个下表字符的码点

04-normalize()

字符合成相关

05-includes(), startsWith() ,endsWith()

includes()是否包含, 第二个参数表示从第n个到结束

startsWith()是否开始于头部, 第二个参数表示从第n个到结束

endsWith()是否结束于尾部,第二个参数表示从开头到第n个,不包含

06-repeat()

返回调用该方法的字符串重复n次之后的字符串

07-padStart(),padEnd()

第一个参数表示规定的字符串长度

第二个参数表示用什么来补全

1
2
3
4
5
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

08-trimStart(),trimEnd()

消除字符串前后的空格

09-matchAll()

返回一个正则表达式在当前字符串的所有匹配

05-正则扩展

跳过

06-数值扩展

01-二进制和八进制表示法

使用0b或者0B表示二进制前缀

使用0o或者0O表示八进制前缀

02-Number.isFinite(), Number.isNaN()

检测是否有限,是否为NaN

03-Number.parseInt(), Number.parseFloat()

04-Number.isInteger()

判断是否整数

对精度要求高不要使用

05-Number.EPSILON()

用于提供一个js能够识别的最小精度数字

用于解决类似0.1+0.2!==0.3的问题

06-安全整数和 Number.isSafeInteger()

判断是否安全整数

安全整数:整数范围在-2^532^53之间(不含两个端点)的数

07-Math对象扩展

01-Math.trunc()

去除小数部分,如4.5=》4,-4.5=》-4

02-Math.sign()

判断是正数负数还是零,返回值为+1,-1,0,NaN

03-Math.cbrt()

计算立方根

04-Math.clz32()

转换为32位无符号整数

05-Math.imul()

返回两个有符号32位整数相乘的结果

相对于a*b,优点在于溢出的时候可以正确返回低位的数值

06-Math.fround()

将64位双精度浮点数转换为32位单精度浮点数

07-Math.hypot()

返回所有参数的平方和的平方根

08-对数方法(略)

09-双曲函数方法(略)

08-指数运算符

1
2
2**3=8
2**2=4

09-BigInt数据类型

没有位数限制,不会像普通数值一样丢失精度,但是只能保存整数

表示方法

1
a = 123456789123456n

07-函数扩展

01-函数参数默认值

01-基本用法

1
2
3
function log(x, y = 'World') {
console.log(x, y);
}

02-可以与解构赋值语法一起使用

详情看上方解构赋值语法

03-有默认值的参数应该放后面

04-length问题

函数的length函数会返回该函数的参数个数,使用默认值会使计数粗线问题,返回0

05-作用域

参数使用默认值时,参数会自己形成一个作用域,先在当前作用域内找变量,再找外部变量

06-应用

可用于参数不得省略,用到再查

02-rest参数

01-用法

用于收集多余的参数

1
2
3
4
5
6
7
8
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10

这个写法可以收集任意数量的参数,并进行数据运算

与arguments的区别,arguments是一个类似于数组的对象,但不是数组,想要使用数组的方法需要进行Array.prototype.slice.call进行转换才能使用数组方法

02-rest参数只能是最后一个参数

03-影响严格模式

使用默认值、解构赋值、或者扩展运算符,函数内部不能显式设置严格模式,否则报错

03-箭头函数

01-简单使用

1
2
3
4
5
6
var f = v => v;

// 等同于
var f = function (v) {
return v;
};

02-多个参数

1
var sum = (num1, num2) => { return num1 + num2; }

03-如果返回的参数是对象

1
let getTempItem = id => ({ id: id, name: "Temp" });

04-注意点

  1. this的指向问题,是指向定义时所在的对象,而不是使用时所在的对象
  2. 不可以当做构造函数
  3. 不可以使用arguments对象
  4. 不可以使用yield命令(这个命令没见过不知道做啥的,以后补充)

05-优点

可以用来封装回调函数,这样this只会指向创建他的对象,因此在外部调用这个方法的时候,不会因为this指向document而导致程序出错

这个优点同时也是缺点

当this需要动态变化和定义对象方法的时候,使用箭头函数会固化this指向,导致无法正确执行函数

04-尾调用优化

01-尾调用实例

1
2
3
function f(x){
return g(x);
}

最后一步调用另外一个函数,就是尾调用,只有像上面格式才是,其他无论长得多像都不是尾调用

02-尾调用的作用

在函数内调用另外一个函数的时候,需要保存父函数的作用域,存入到调用栈中,如果嵌套层数过多的话,会导致调用栈过于庞大,占用过多的内存。

所以使用尾调用,因为已经没有别的可以执行了,所以系统可以放心的把外层的调用帧释放掉,只生成内层函数的调用帧。

多使用尾调用,每次调用函数的调用帧就只有一层,可以大大节省内存空间

05-尾递归优化

01-尾递归

最后一步调用自身

02-尾递归的作用

当运行一些需要递归多次的算法的时候,容易发生栈溢出,使用尾递归可以把上层调用栈释放掉,阻止了栈溢出。

08- 数组扩展

01-扩展运算符

1
console.log(...[1, 2, 3])

会将数组拆分为逗号相隔的参数序列

01-数组复制

正常我们复制数组只是声明一个新的变量名,并让他指向旧数组的地址,使用旧变量名依然会影响新变量名。

使用扩展运算符可以使用类似于解构的语法来进行深拷贝。

1
2
3
4
5
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

02-数组赋值

注意事项:用于数组赋值的时候,扩展运算符只能放在最后一步

03-拆分字符串

1
2
[...'hello']
// [ "h", "e", "l", "l", "o" ]

10-对象新增方法

03-Object.getOwnPropertyDescriptors()

01-主要作用

返回一个对象中所有的属性组合形成的对象,key为属性,value为该属性的描述对象,包括get&set方法,writeable:是否可读写,configurable:能否修改访问器属性,enumerable:是否可以使用for in循环出来。

补充重新理解的点:

01-call()和apply()

主要作用都是改变this的指向

1
2
A.call(B,arg1,arg2,arg3)
A.apply(B,args)

以上都是使用A的方法,只不过this这个时候指向B

可以理解为B使用了A的方法

02-get&set方法

类内部自带的方法,重写之后,涉及到属性的修改或者获取的操作时,会执行方法的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Num {
constructor(num) {
this._num = num;
}

get num() {
return this._num;
}

set num(num) {
this._num = num+1;
}
}

var test = new Num(9);
console.log(test.num); //9
test.num = 99;
console.log(test.num); //100

有点难理解的点:

箭头函数,this的指向问题