Number
判断一个值是不是NaN
现在在JS中,判断一个值是否为 NaN
,可以直接使用 Number.isNaN
方法。如下:
const number = 3;
Number.isNaN(number);
String
matchAll
在最新的 javascript
版本中,字符串已经有了一个新的方法: matchAll ,这个方法的参数是一个正则表达式,但这个正则表达式一定要包含 g
标记。如下:
const string = "hello javascript!";
const reg = /hello/g;
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是整形,所以小数部分会值忽略取整。
类型信息
静态方法
- BigInt.asIntN() 把 BigInt转换为有符号整数
BigInt.asUintN() 把bigInt转换为无符号整数
实例方法
BigInt.prototype.toLocalString() 返回此数字的 language-sensitive 形式的字符串。
- BigInt.prototype.toString() 返回以指定基数(base)表示指定数字的字符串。
BigInt.prototype.valueOf() 返回指定对象的基元值。
使用示例
转换16进制为10进制
const dict: any = {
0: 0n,
1: 1n,
2: 2n,
3: 3n,
4: 4n,
5: 5n,
6: 6n,
7: 7n,
8: 8n,
9: 9n,
a: 10n,
b: 11n,
c: 12n,
d: 13n,
e: 14n,
f: 15n,
A: 10n,
B: 11n,
C: 12n,
D: 13n,
E: 14n,
F: 15n,
};
export function hex2dex(x: string): string {
const array: string[] = x.split("");
const result = array.reverse().reduce((acc, cur, curIndex) => {
if (dict.hasOwnProperty(cur)) {
return acc + dict[cur] * (16n ** BigInt(curIndex));
}
return 0n;
}, 0n);
return result.toString();
}
URL
URL
URL接口用于解析,构造,规范化和编码URLs。提供了方便阅读和修改URL组件的API。
URL的常用属性如下:protocol 协议
- username 用户名
- password 密码
- path 路径
- search 查询参数字符串
- searchParams 查询参数对象
- hash hash值
- host 主机名+端口号
- port 端口号
-
URLSearchParams
URLSearchParams接口定义了一些实用的方法来处理URL的查询字符串。
URLSearchParams有以下方法: append
- delete
- set
- has
- get
- getAll
- keys
- values
- entries
- sort
- toString
需要注意的是,URLSearchParams不会解析完整的URL地址,但可以解析URL的 search部门。
下面是对URLSearchParams的一个应用代码:
function parseSearch(str) {
const url = new URL(str);
const search = url.searchParams;
return Array.from(search.keys()).reduce((acc, cur) => {
if (acc.hasOwnProperty(cur)) {
const val = search.getAll(cur);
return {...acc, [cur]: val}
}
const val = search.get(cur) !== '' ? search.get(cur) : undefined;
return {...acc, [cur]: val}
}, {});
}
const str = 'http://www.a.com/about?a=1&b=2&c=3&c=4&d';
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开发的过程中,难免会遇到使用防抖和节流的时候。这两者有时候会比较容易混淆。在这里记录一下两者的区别和使用场景。
防抖
防抖,顾名思义就是防止抖动。其表现就是如果在指定的时间窗口内事件只触发了一次,那就执行该事件。否则,新触发的时机开始,重新创建一个新的时间窗口,判断是否在指定的时间窗口中事件只触发一次,如此反复。
function debounce(fn,delay) {
let timer = null;
return (...args)=>{
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,args)
},delay)
}
}
节流
节流,就是在指定的时间窗口中,只执行最后一次的事件触发,在最后一次的事件触发之前的事件都会被取消。节流可以保证在指定的时间内总有一次事件触发。
使用setTimeoute实现:
function throttle(fn,delay) {
let timer = null;
return (...args)=>{
if (timer) return;
timer = setTimeout(()=>{
fn.apply(this,args);
timer = null;
},delay)
}
}
使用时间戳实现:
function throttle(fn, delay) {
let prev = 0;
return (...args)=>{
const now = Date.now();
if (now-prev>delay){
fn.apply(this,args);
prev = now;
}
}
}
防抖和节流的区别
对于防抖和节流的区别,通过举例的方式来看比较好理解。
同一个事件,时间窗口的大小都设置为1s,每800ms触发一次。
防抖:在停止触发事件之前,通过防抖控制的事件,一次都不会触发,直到停止触发事件,事件会触发一次。
节流:在停止触发事件之前,事件不会每800ms触发一次,还是变为每1s触发一次。
模拟
模拟实现bind方法
Function.prototype.bound = function (target,...args){
return (...arguments)=>{
return this.apply(target,[...args,...arguments]);
}
}
正则表达式
贪婪模式和非贪婪模式
在JavaScript的正则表达式中,使用的是贪婪模式。有时候,我们需要使用非贪婪模式。那么我们需要如果去实现?而贪婪模式和非贪婪模式又都是什么?又有什么区别呢?现在我们就来一探究竟。
贪婪模式和非贪婪模式的区别
const str = `I love JavaScript! I don't love Java!`;
const reg = /love (.+)!/i; // 默认的贪婪语法
const reg1 = /love (.+?)!/i; // 非贪婪语法
reg.exec(str); // ["love JavaScript! I love TypeScript!","JavaScript! I love TypeScript"]
reg1.exec(str); // ["love JavaScript!", "JavaScript"]
我们可以看到,在默认的贪婪模式下,正则表达式会尽可能多的匹配符合要求的字符串,有时候这并不是我们想要的是最少的匹配。这个时候我们就要使用非贪婪语法了。
事件
防止用户粘贴、复制和剪切
在一些场景中,我们会有防止用户对选择的内容进行复制,粘贴和剪切的需求。在这个时候,我们只要使用对应的三个方法就行。分别对应的是oncopy
,onpaste
和oncut
。
防复制
oncopy
事件在用户对选择的文件进行复制的时候触发。这里的复制包括:
ctrl+c
- 菜单中 Edit(编辑)->Copy(复制)
- 快捷菜单中的Copy(复制)命令
要想阻止用户的复制行为, 使用下面的代码就可以。
function onCopy(event){
/*
这里可以添加一些自定义的逻辑
*/
event.preventDefault();
}
防粘贴
onpaste
事件在用户对选择的文件进行粘贴的时候触发。这里的粘贴包括:
ctrl+v
- 菜单中 Edit(编辑)->Paste(粘贴)
- 快捷菜单中的Paste(粘贴)命令
要想阻止用户的粘贴行为, 使用下面的代码就可以。
function onPaste(event){
/*
这里可以添加一些自定义的逻辑
*/
event.preventDefault();
}
防剪切
oncut
事件在用户对选择的文件进行剪切的时候触发。这里的复制包括:
ctrl+x
- 菜单中 Edit(编辑)->Cut(剪切)
- 快捷菜单中的Cut(剪切)命令
要想阻止用户的剪切行为, 使用下面的代码就可以。
function onCut(event){
/*
这里可以添加一些自定义的逻辑
*/
event.preventDefault();
}
自定义事件
在JavaSciprt和浏览器集成的时候,JavaScript提供了一个自定义事件的方法,我们可以使用这个自定义事件来做一些事情,比如实现自己的发布订阅方法,我实现这个需要我们配置使用addEventListener
,dispatchEvent
和CustomEvent
三个方法。先在这里以一个示例说明:
document.body.addEventListener("javascript", function(e){
console.log(e.detail)
});
const event = new CustomEvent("javascript", {
detail: {
type: "customEvent"
}
});
obj.dispatchEvent(event);
在上面的这个示例中,`addEventListener`用于添加事件监听,而`dispatchEvent`用于事件分发,`dispatchEvent`接收一个事件作为参数。这个事件是由`CustomEvent`来定义的。<br />`CustomEvent`构造函数接收两个参数,第一个参数是一个事件名称,用一个字符串表示。第二个参数是一个可选参数。这个参数是一个`customEventInit`类型,这个类型是一个对象,这个对象由三个字段组成:
- detail 这个值是一个可选参数,其默认值为
null
。这个值可以是任意类型,比如可以是boolean
,number
,string
,object
,array
等等。这是一个与event
相关的值 - bubbles 这个值也是一个可选参数,其类型是一个
boolean
类型的值,代表了这个事件是否冒泡。 - cancelable 誰值也是一个可选参数,其类型是一个
boolean
类型的值,代表了这个事件是否可以被取消。