0%

Set

Set 类似于数组,但是成员的值都是唯一的,没有重复的值。

1
2
3
4
5
6
// 数组去重
const arr = [1, 2, 3, 3];
const newArr = [...new Set(arr)];

// 字符串去重
[...new Set('ababbc')].join('');

实例的属性和方法

  • size:返回 Set 实例成员总数
  • add(value):添加某个值,返回 Set 结构本身
  • delete(value):删除某个值,返回布尔值,表示是否删除成功
  • has(value):返回布尔值,表示该值是否为 Set 的成员
  • clear():清除所有值

遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():遍历每个成员

Map

Map 类似于对象,也是键值对的结合,但“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

1
2
3
4
const m = new Map();
const o = { p: 'Hello World' };
m.set(o, 'content');
m.get(o); // 'content'

Map 也接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

1
2
3
4
5
6
7
8
const map = new Map([
['name', '张三'],
['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"

实例的属性和方法

  • size:返回成员总数
  • set(key, value):返回整个 Map 结构
  • get(key):根据 key 返回 vlaue
  • has(key):是否有某个键
  • delete(key):删除某个键,返回布尔值
  • clear():清除所有成员

遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():遍历每个成员

扩展运算符 spread

... 好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

1
2
3
4
5
6
7
8
9
10
11
console.log(...[1, 2, 3]) // 1 2 3

// 复制数组
const a1 = [1, 2];
const a2 = [...a1];

// 合并数组
const a3 = [...a1, ...a2];

// 字符串
[...'hello'] // ['h', 'e', 'l', 'l', 'o']

原型方法

Array.from

用于将类数组对象和可遍历对象(iterable,包括Set 和 Map)转为真正的数组。

1
2
3
4
5
6
7
8
[...document.querySelectorAll('div')] // 类数组,通过DOM接口返回的NodeList集合

function foo() {
const args = [...arguments]; // 类数组,函数内部的arguments对象
}

Array.from({ length: 3 }); // 类数组对象,必须有length属性
// [ undefined, undefined, undefined ]

Array.from 还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

1
Array.from([1, 2, 3], (x) => x * x) // 等同于又调用了一个map方法

Array.of()

用于将一组值,转化为数组

1
Array.of(3, 11, 8) // [3,11,8]

实例方法

copyWithin()

在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

1
Array.prototype.copyWithin(target, start = 0, end = this.length)

接受三个参数:

  • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
  • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
  • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。
1
2
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
// 上面代码表示将从 3 号位直到数组结束的成员(4 和 5),复制到从 0 号位开始的位置,结果覆盖了原来的 1 和 2。

find() 和 findIndex()

find 方法用于找出第一个符合条件的数组成员。参数是一个回调函数,将函数返回值为true的成员返回。

findIndex 方法与 find 方法很相似。只不过返回的是数组成员的位置。

fill()

使用给定值,填充一个数组。

1
2
3
4
['a', 'b', 'c'].fill(7) // [7, 7, 7]

// 还接受第二个和第三个参数,用于指定填充的起始位置和结束位置
['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']

entries(),keys(),values()

这三个方法都用于遍历数组。它们都返回一个遍历器对象(Iterator),可以用 for...of 循环进行遍历,唯一的区别是 keys() 是对键名的遍历、values() 是对键值的遍历,entries() 是对键值对的遍历。

includes()

该方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。之前我们通常使用数组的 indexOf 方法检查是否包含某个值。
第一个参数是要搜索的值。第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

1
[1, 2, 3].includes(2)     // true

flat(),flatMap()

数组的成员有时还是数组,flat() 用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
flat() 默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将 flat() 方法的参数写成一个整数,表示想要拉平的层数,默认为1。
如果不管有多少层嵌套,都要转成一维数组,可以用 Infinity 关键字作为参数。

1
2
3
4
5
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]

[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]

[1, 2, [3, [4, 5]]].flat(Infinity) // [1, 2, 3, 4, 5]

flatMap() 方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

实例方法

includes(),startsWith(),endsWith()

  • includes:返回布尔值,表示是否找到了参数字符串
  • startsWith :返回布尔值,表示参数字符串是否在原字符串的头部
  • endsWith:返回布尔值,表示参数字符串是否在字符串尾部
    以上三个方法都有两个参数,第一个参数是要查找的字符串,第二个参数是开始查找的位置(endsWidth不同,代表针对这个位置之前的字符查找)。

repeat()

返回一个新字符串,表示将原字符串重复n次

1
'x'.repeat(3) // "xxx"

padStart(),padEnd()

补全字符串长度。如果某个字符串不够指定长度,会在头部和尾部补全。
这两个方法都接受两个参数,第一个是字符串补全后的长度,第二个参数是用来补全的字符串。

1
2
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'

trimStart(),trimEnd()

这两个方法与 trim() 一致,用来消除字符串头部或尾部的空格。返回新字符串,不会修改原始字符串。

matchAll()

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

codePointAt()

normalize()

原型方法

String.fromCodePoint()

从 Unicode 码点返回对应字符。类似于ES5中的 String.fromCharCode(),但弥补了它的不足,可以识别大于 0xFFFF 的字符。

String.raw()

该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法。

JavaScript 是一门单线程语言,为了使主线程不阻塞,Event Loop 就应运而生了。Event LoopJavaScript 的执行机制。

image

  • 同步和异步任务分别进入不同的执行“场所”,同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
阅读全文 »

节流(throttle)和防抖(debounce)在前端使用还是挺频繁的,以前一直是用 Lodash 中提供的方法。今天用这篇文章简单了解下这两个方法的实现原理。

节流和防抖函数都利用了闭包的特性。函数里面嵌套了另一个函数,里面的函数引用了外面函数作用域中定义的变量,导致函数执行完后,这个变量不会被垃圾回收机制回收。因此节流防抖函数可以利用这一特性,根据外函数变量的值,对函数是否再次调用做出针对性处理。

阅读全文 »

网页布局(layout)是 CSS 的一个重点应用。传统的网页布局基于盒状模型,依赖 display + position + float,但它对一些特殊布局不容易实现。

Flex 是 Flexible Box 的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性。它可以简便、完整、响应地实现各种页面布局。

阅读全文 »

async 函数是 Generator 函数的语法糖。async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await

async 函数对 Generator 函数的改进,有以下四点:

  • 内置执行器
  • 更好的语义
  • 更广的适用性
  • 返回的是 Promise

React 的官方定义是用于构建用户界面的 JavaScript 库。通常组件内的数据来源于 stateprops,由于 React 的特点之一单向数据流,当渲染一个组件的数据来源于 props 时,通常情况下是 A -> B,但是随着业务复杂度的增加、组件层级增加,可能会变成 A -> B -> C -> D -> E

阅读全文 »