Number

判断一个值是不是NaN

现在在JS中,判断一个值是否为 NaN ,可以直接使用 Number.isNaN 方法。如下:

  1. const number = 3;
  2. Number.isNaN(number);

String

matchAll

在最新的 javascript 版本中,字符串已经有了一个新的方法: matchAll ,这个方法的参数是一个正则表达式,但这个正则表达式一定要包含 g 标记。如下:

  1. const string = "hello javascript!";
  2. const reg = /hello/g;
  3. const result = string.matchAll(reg);

当 reg 不包含 g 标记时,javascript会报类型错误。matchAll方法的返回值是一个迭代器。迭代器的每一项是通过正则表达式匹配到的结果。因为返回值一个迭代器,所以我们只可以对其消费一次。返回的迭代器可以让我们可以更加灵活的处理结果,可以用 iterator.next() 的方法处理,也可以用 Array.from()和者扩展运算符…展开为数组。

Date

问题:
在JS中,如果你使用的时间早于1901年,那么经过JS的Date对象的转换,则是多出5分43秒.

BigInt

在最近的 JavaScript 中,新添加了一个叫做 BigInt 的类型。 BigInt 是一种内置对象。它提供了一种方法来表示大于 2``53``-1 的整数。 BigInt 可以用来表示任意大小的整数。这在一定程序上解决了 JavaScript 中表示整数有限的问题。

表示方法

BigInt的表示方法有两种:

  • 直接在整数后加 n
  • 调用函数 BigInt()

    注意:BigInt是一个函数,值不是构造函数,所以不能使用 new 关键字。即不能这样使用 new BigInt

BigInt不能直接和Number类型进行计算,两者必须要转换为同一种类型,而且 BigInt不能使用 Math 对象中的方法。为了避免在 BigInt 转换为Number类型时,因为丢失精度产生精度不准。我们往往把Number转为BigInt来计算。BigInt类型支持 + , - , * , / , % , ** 等计算。如

  • 2n + 3n
  • 3n - 2n
  • 3n * 2n
  • 3n / 2n
  • 3n % 2n
  • 3n ** 2n

    注意:当使用 / 时,由于 BigInt是整形,所以小数部分会值忽略取整。

类型信息

typeOf 1n; // bigint

静态方法

  • BigInt.asIntN() 把 BigInt转换为有符号整数
  • BigInt.asUintN() 把bigInt转换为无符号整数

    实例方法

  • BigInt.prototype.toLocalString() 返回此数字的 language-sensitive 形式的字符串。

  • BigInt.prototype.toString() 返回以指定基数(base)表示指定数字的字符串。
  • BigInt.prototype.valueOf() 返回指定对象的基元值。

    使用示例

    转换16进制为10进制

    1. const dict: any = {
    2. 0: 0n,
    3. 1: 1n,
    4. 2: 2n,
    5. 3: 3n,
    6. 4: 4n,
    7. 5: 5n,
    8. 6: 6n,
    9. 7: 7n,
    10. 8: 8n,
    11. 9: 9n,
    12. a: 10n,
    13. b: 11n,
    14. c: 12n,
    15. d: 13n,
    16. e: 14n,
    17. f: 15n,
    18. A: 10n,
    19. B: 11n,
    20. C: 12n,
    21. D: 13n,
    22. E: 14n,
    23. F: 15n,
    24. };
    25. export function hex2dex(x: string): string {
    26. const array: string[] = x.split("");
    27. const result = array.reverse().reduce((acc, cur, curIndex) => {
    28. if (dict.hasOwnProperty(cur)) {
    29. return acc + dict[cur] * (16n ** BigInt(curIndex));
    30. }
    31. return 0n;
    32. }, 0n);
    33. return result.toString();
    34. }

    URL

    URL

    URL接口用于解析,构造,规范化和编码URLs。提供了方便阅读和修改URL组件的API。
    URL的常用属性如下:

  • protocol 协议

  • username 用户名
  • password 密码
  • path 路径
  • search 查询参数字符串
  • searchParams 查询参数对象
  • hash hash值
  • host 主机名+端口号
  • port 端口号
  • hostname 主机名

    URLSearchParams

    URLSearchParams接口定义了一些实用的方法来处理URL的查询字符串
    URLSearchParams有以下方法:

  • append

  • delete
  • set
  • has
  • get
  • getAll
  • keys
  • values
  • entries
  • sort
  • toString

需要注意的是,URLSearchParams不会解析完整的URL地址,但可以解析URL的 search部门。
下面是对URLSearchParams的一个应用代码:

  1. function parseSearch(str) {
  2. const url = new URL(str);
  3. const search = url.searchParams;
  4. return Array.from(search.keys()).reduce((acc, cur) => {
  5. if (acc.hasOwnProperty(cur)) {
  6. const val = search.getAll(cur);
  7. return {...acc, [cur]: val}
  8. }
  9. const val = search.get(cur) !== '' ? search.get(cur) : undefined;
  10. return {...acc, [cur]: val}
  11. }, {});
  12. }
  13. const str = 'http://www.a.com/about?a=1&b=2&c=3&c=4&d';
  14. const obj = getSearch(); // { a: '1', b: '2', c: [ '3', '4' ], d: undefined }

类型转换

ToString

其他类型转换为字符串类型,一般符合以下的规则:

  • null -> “null”
  • undefined -> “undefined”
  • true -> “true”
  • false -> “false”
  • 数字使用通用规则
  • Symbol不能转换为字符串,会报错 TypeError
  • 对象 -> “[object Object]” 没有设置toString方法时
  • 数组 -> 相当于使用 Array.prototype.join() 的返回结果
  • 函数 -> 函数的书写内容

    ToNumber

    其他类型转换为数值类型,一般符合以下的规则:

  • true -> 1

  • false -> 0
  • “” -> 0
  • {} -> 0

防抖和节流

在使用JavaScript开发的过程中,难免会遇到使用防抖节流的时候。这两者有时候会比较容易混淆。在这里记录一下两者的区别和使用场景。

防抖

防抖,顾名思义就是防止抖动。其表现就是如果在指定的时间窗口内事件只触发了一次,那就执行该事件。否则,新触发的时机开始,重新创建一个新的时间窗口,判断是否在指定的时间窗口中事件只触发一次,如此反复。

  1. function debounce(fn,delay) {
  2. let timer = null;
  3. return (...args)=>{
  4. clearTimeout(timer);
  5. timer = setTimeout(()=>{
  6. fn.apply(this,args)
  7. },delay)
  8. }
  9. }

节流

节流,就是在指定的时间窗口中,只执行最后一次的事件触发,在最后一次的事件触发之前的事件都会被取消。节流可以保证在指定的时间内总有一次事件触发。
使用setTimeoute实现:

  1. function throttle(fn,delay) {
  2. let timer = null;
  3. return (...args)=>{
  4. if (timer) return;
  5. timer = setTimeout(()=>{
  6. fn.apply(this,args);
  7. timer = null;
  8. },delay)
  9. }
  10. }

使用时间戳实现:

  1. function throttle(fn, delay) {
  2. let prev = 0;
  3. return (...args)=>{
  4. const now = Date.now();
  5. if (now-prev>delay){
  6. fn.apply(this,args);
  7. prev = now;
  8. }
  9. }
  10. }

防抖和节流的区别

对于防抖和节流的区别,通过举例的方式来看比较好理解。
同一个事件,时间窗口的大小都设置为1s,每800ms触发一次。
防抖:在停止触发事件之前,通过防抖控制的事件,一次都不会触发,直到停止触发事件,事件会触发一次。
节流:在停止触发事件之前,事件不会每800ms触发一次,还是变为每1s触发一次。

模拟

模拟实现bind方法

  1. Function.prototype.bound = function (target,...args){
  2. return (...arguments)=>{
  3. return this.apply(target,[...args,...arguments]);
  4. }
  5. }

正则表达式

贪婪模式和非贪婪模式

在JavaScript的正则表达式中,使用的是贪婪模式。有时候,我们需要使用非贪婪模式。那么我们需要如果去实现?而贪婪模式和非贪婪模式又都是什么?又有什么区别呢?现在我们就来一探究竟。

贪婪模式和非贪婪模式的区别

  1. const str = `I love JavaScript! I don't love Java!`;
  2. const reg = /love (.+)!/i; // 默认的贪婪语法
  3. const reg1 = /love (.+?)!/i; // 非贪婪语法
  4. reg.exec(str); // ["love JavaScript! I love TypeScript!","JavaScript! I love TypeScript"]
  5. reg1.exec(str); // ["love JavaScript!", "JavaScript"]

我们可以看到,在默认的贪婪模式下,正则表达式会尽可能多的匹配符合要求的字符串,有时候这并不是我们想要的是最少的匹配。这个时候我们就要使用非贪婪语法了。

事件

防止用户粘贴、复制和剪切

在一些场景中,我们会有防止用户对选择的内容进行复制,粘贴剪切的需求。在这个时候,我们只要使用对应的三个方法就行。分别对应的是oncopyonpasteoncut

防复制

oncopy事件在用户对选择的文件进行复制的时候触发。这里的复制包括:

  • ctrl+c
  • 菜单中 Edit(编辑)->Copy(复制)
  • 快捷菜单中的Copy(复制)命令

要想阻止用户的复制行为, 使用下面的代码就可以。

  1. function onCopy(event){
  2. /*
  3. 这里可以添加一些自定义的逻辑
  4. */
  5. event.preventDefault();
  6. }

防粘贴

onpaste事件在用户对选择的文件进行粘贴的时候触发。这里的粘贴包括:

  • ctrl+v
  • 菜单中 Edit(编辑)->Paste(粘贴)
  • 快捷菜单中的Paste(粘贴)命令

要想阻止用户的粘贴行为, 使用下面的代码就可以。

  1. function onPaste(event){
  2. /*
  3. 这里可以添加一些自定义的逻辑
  4. */
  5. event.preventDefault();
  6. }

防剪切

oncut事件在用户对选择的文件进行剪切的时候触发。这里的复制包括:

  • ctrl+x
  • 菜单中 Edit(编辑)->Cut(剪切)
  • 快捷菜单中的Cut(剪切)命令

要想阻止用户的剪切行为, 使用下面的代码就可以。

  1. function onCut(event){
  2. /*
  3. 这里可以添加一些自定义的逻辑
  4. */
  5. event.preventDefault();
  6. }

自定义事件

在JavaSciprt和浏览器集成的时候,JavaScript提供了一个自定义事件的方法,我们可以使用这个自定义事件来做一些事情,比如实现自己的发布订阅方法,我实现这个需要我们配置使用addEventListener,dispatchEventCustomEvent三个方法。先在这里以一个示例说明:

  1. document.body.addEventListener("javascript", function(e){
  2. console.log(e.detail)
  3. });
  4. const event = new CustomEvent("javascript", {
  5. detail: {
  6. type: "customEvent"
  7. }
  8. });
  9. obj.dispatchEvent(event);
  1. 在上面的这个示例中,`addEventListener`用于添加事件监听,而`dispatchEvent`用于事件分发,`dispatchEvent`接收一个事件作为参数。这个事件是由`CustomEvent`来定义的。<br />`CustomEvent`构造函数接收两个参数,第一个参数是一个事件名称,用一个字符串表示。第二个参数是一个可选参数。这个参数是一个`customEventInit`类型,这个类型是一个对象,这个对象由三个字段组成:
  • detail 这个值是一个可选参数,其默认值为null。这个值可以是任意类型,比如可以是boolean,number,string,object,array等等。这是一个与event相关的值
  • bubbles 这个值也是一个可选参数,其类型是一个boolean类型的值,代表了这个事件是否冒泡。
  • cancelable 誰值也是一个可选参数,其类型是一个boolean类型的值,代表了这个事件是否可以被取消。

image.png