let和const
let:声明变量
const:声明只读常量且必须赋初始值,常量值不可修改,声明对象可修改对象的属性
- 没有变量提升(即:脚本开始运行时提前声明为unefined的变量)、拥有临时性死区(声明前调用会报错)
- 不允许重复声明同名变量
- 拥有块级作用域(即:超出当前变量声明作用域无法调用该变量)
解构赋值
数组:位置顺序解构
对象:数据结构相同且同名变量解构
字符串 :位置顺序解构,可解构length(let {length:len} = ‘test’)
函数:根据传入参数类型不同 按照以上规则解构
- 可指定默认值(即:let [f = ‘ff’] = [] || let {obj=“obj”} = {})
- 可完全解构(即:等号两边数据结构完全相等)
- 可不完全解构(即:等号两边数据结构相等,但等号左边只解构部分变量)
模板字符串
` ` 使用模板字符串
${}在模板字符串中使用变量
- 可多行使用(即 “ 可换行)
- 可使用反斜杠转义\(即 \ ` 使用)
- 可通过 ${} 调用函数(即${fn()})
- 可嵌套模板字符串 总之,hin实用
字符串拓展方法
includes():返回布尔值,表示是否找到了参数字符串;
let str = 'Uyoahz!';
str.includes('a') // true
startsWith():返回布尔值,表示字符串是否以参数字符串开头,区分大小写。
str.startsWith('Uy') // true
str.startsWith('uy') // false
endsWith():返回布尔值,表示字符串是否以参数字符串结束,同样区分大小写。
str.endsWith('!') // true
repeat():返回一个新字符串,表示将原字符串重复n次。
'hello'.repeat(2) // "hellohello"
padStart():字符串不够指定长度,将头部补全。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
padEnd():字符串不够指定长度,将尾部补全。
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
trimStart():消除字符串头部的空格(返回的都是新字符串,不会修改原始字符串)。
const s = ' abc ';
s.trimStart() // "abc "
trimEnd():消除尾部的空格 (返回的都是新字符串,不会修改原始字符串)
s.trimEnd() // " abc"
matchAll():返回一个正则表达式在当前字符串的所有匹配
replaceAll():可以一次性替换所有匹配。
'aabbcc'.replaceAll('b', '_') // 'aa__cc'
at():接受一个整数作为参数,返回参数指定位置的字符,支持负索引
const str = 'hello';
str.at(1) // "e"
数值拓展
二进制
八进制
数值分隔符
- 不能放在数值的最前面(leading)或最后面(trailing)。
- 不能两个或两个以上的分隔符连在一起。
- 小数点的前后不能有分隔符。
- 科学计数法里面,表示指数的e或E前后不能有分隔符。
BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示
- 可以使用
BigInt()进行类型转换 - BigInt 类型的数据必须添加后缀
n。 - BigInt 不能与普通数值进行混合运算。
- 可以使用
Boolean()、Number()和String()这三个方法,将 BigInt 可以转为布尔值、数值和字符串类型,转为字符串时后缀n会消失。 - BigInt 与字符串混合运算时,会先转为字符串,再进行运算。
实例方法
用的最多的也就前两个了
Number.isFinite():用来检查一个数值是否为有限的(finite),即不是Infinity
Number.isNaN():用来检查一个值是否为NaN(Not a Number)
Number.isInteger(): 用来判断一个数值是否为整数
Number.parseInt:用来转换为正整数数值
Number.parseFloat:来转换为双浮点数值
Number.EPSILON:极小的常量,它表示 1 与大于 1 的最小浮点数之间的差
Number.MAX_SAFE_INTEGER: 表示javascript能精表示的整数最大值
Number.MIN_SAFE_INTEGER: 表示javascript能精表示的整数最小值
Number.isSafeInteger():用来判断一个整数是否落在javascript能表示最大值和最小值之内
Math.trunc():用于去除一个数的小数部分,返回整数部分
Math.sign():用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值
Math.cbrt():用于计算一个数的立方根
Math.clz32():将参数转为 32 位无符号整数的形式,然后返回这个 32 位值里面有多少个前导 0
Math.imul:返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数
Math.fround:返回一个数的32位单精度浮点数形式
Math.hypot:返回所有参数的平方和的平方根
Math.expm1(x):返回 ex - 1,即Math.exp(x) - 1
Math.log1p(x):返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN
Math.log10(x):返回以 10 为底的x的对数。如果x小于 0,则返回 NaN
Math.log2(x):返回以 2 为底的x的对数。如果x小于 0,则返回 NaN
Math.sinh(x): 返回x的双曲正弦
Math.cosh(x): 返回x的双曲余弦
Math.tanh(x): 返回x的双曲正切
Math.asinh(x): 返回x的反双曲正弦
Math.acosh(x): 返回x的反双曲余弦
Math.atanh(x): 返回x的反双曲正切
函数拓展
函数默认值
(即:函数的参数指定默认值)
- 可以和解构一起使用(即:
function foo({x, y = 5}){}) - 通常参数默认值的位置在尾部,方便使用默认值忽略(即:
function f(x = 1, y),只传一个参数则x无法正常使用默认值忽略) - 使用默认值会导致函数了
length属性失真(即:因为length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了) - 设置默认值会在函数初始化时产生单独作用域,初始化结束作用域消失 即:
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2) // 2
rest参数
name属性
箭头函数
=> (即:function foo = () => {})
- 没有自己的
this对象,内部使用this会采用调用时上级作用域this - 不可以对箭头函数使用
new命令,否则会抛出错误 - 不可以使用
arguments对象,如果要用,可以用rest参数代替 - 不可以使用
yield命令,箭头函数不能用作Generator函数Function.prototype.toString()(即:方法返回函数代码本身,以前会省略注释和空格)catch的参数省略(即:try {} catch {})
数组拓展
拓展运算符
...将一个数组转为用逗号分隔的参数序列
数组空位
数组的某一个位置没有任何值,ES6则是明确将空位转为undefined
静态方法
Array.from() 用于将两类对象转为真正的数组: (array-like object)和(iterable)和 (Set) 和(Map)
即:
let s = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr2 = Array.from(s); // ['a', 'b', 'c']
Array.of() 用于将一组值,转换为数组 (即:Array.of(3, 11, 8) // [3,11,8])
实例方法
copyWithin()在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原数组),返回当前数组。会修改当前数组 (即:[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5])find()用于找出第一个符合条件的数组成员。然后返回该成员。如果没有符合条件的成员,则返回undefined。findIndex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。fill()使用给定值,填充一个数组 (即:['a', 'b', 'c'].fill(7) // [7, 7, 7])includes()返回一个布尔值,表示某个数组是否包含给定的值flat()将多维数组处理成一维数组,返回一个新数组flatMap()使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同 (即:[1, 2, [3], [4, 5], 6].flatMap(num => num) // [1, 2, 3, 4, 5, 6])at()ES2022新增,接受一个整数作为参数,返回对应位置的成员,并支持负索引。这个方法不仅可用于数组,也可用于字符串和类型数组 (即:[5, 12, 8, 130, 44].at(-2) // 130)
对象拓展
属性简洁表示法
允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
即:const foo = {name:name,method(){}}
属性名表达式 字面量定义对象(即:obj['a'+'bc'] = 123; )
方法name属性 将对象方法函数,返回函数名
如果使用取值函数和存值函数则如下:
const obj = {
get foo() {},
set foo(x) {}
};
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"
descriptor.set.name // "set foo"
super
指向当前对象的原型对象。(即:super.xxx等同于Object.getPrototypeOf(this).xxx)
静态方法
Object.getOwnPropertyNames()返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
Object.getOwnPropertySymbols()返回一个数组,包含对象自身的所有 Symbol 属性的键名。
Reflect.ownKeys() 返回一个数组,包含对象自身的(不含继承的)所有键名
Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()、Reflect.ownKeys()都遵守同样的属性遍历的次序规则
- 首先遍历所有数值键,按照数值升序排列。
- 其次遍历所有字符串键,按照加入时间升序排列。
- 最后遍历所有 Symbol 键,按照加入时间升序排列。
Object.is() 方法判断两个值是否为同一个值。
Object.assign() 忽略enumerable为false的属性,属性从一个或多个源对象复制到目标对象,返回修改后的对象。因为 Object.assign() 只复制属性值,假如源对象是一个对象的引用,它仅仅会复制其引用值。
Object.getOwnPropertyDescriptors() 所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。
__proto__属性 用来读取或设置当前对象的原型对象
Object.setPrototypeOf() 用来设置一个对象的原型对象(prototype),返回参数对象本身
Object.getPrototypeOf() 用于读取一个对象的原型对象
Object.entries() 返回数据的迭代对象,包含该对象的键值对数组
Object.keys() 返回数据的迭代对象,包含该对象的键名数组
Object.values() 返回数据的迭代对象,包含该对象的值名数组
Object.fromEntries()用于将一个键值对数组转为对象。
Object.hasOwn() 判断是否为自身的属性
运算符拓展
指数运算符
(即:**) 右结合,多个指数运算符连用时,是从最右边开始计算
链判断运算符
ES2020 引入了“链判断运算符” 判断对象是否存在。
短路机制 ?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行
括号的影响 如果有圆括号包裹,只对圆括号颞部产生影响 (即(a?.b).c)
右侧不得为十进制数值 (即:foo?.3:0 会被解析成三元运算符进行处理)
obj?.prop// 对象属性是否存在obj?.[expr]// 同上func?.(...args)// 函数或对象方法是否存在
Null 判断运算符
ES2020 Null 判断运算符?? 只有运算符左侧的值为null或undefined时,才会返回右侧的值 (即:user.name ?? 'zhangsan')
逻辑赋值运算符
ES2021 引入 三个运算符||=、&&=、??=相当于先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算。
x ||= y==x || (x = y)x &&= y==x && (x = y)x ??= y==x ?? (x = y)
Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
Proxy 目标对象的透明代理 即不做任何拦截的情况下,也无法保证与目标对象的行为一致 ,因为 Proxy 代理目标对象内部的this关键字会指向 Proxy 代理
支持的拦截方法
get(target, propKey, receiver) 拦截对象属性的读取 (即:proxy.foo和proxy['foo'])
set(target, propKey, value, receiver) 拦截对象属性的设置,返回一个布尔值(即:proxy.foo = v或proxy['foo'] = v)
has(target, propKey) 拦截 in 操作符的捕捉器。(即:propKey in proxy)
deleteProperty(target, propKey) 拦截delete 操作符的捕捉器。(即:delete proxy[propKey])
ownKeys(target) 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性
getOwnPropertyDescriptor(target, propKey) 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
defineProperty(target, propKey, propDesc) 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
preventExtensions(target) 拦截Object.preventExtensions(proxy),返回一个布尔值。
getPrototypeOf(target) 拦截Object.getPrototypeOf(proxy),返回一个对象。
isExtensible(target) 拦截Object.isExtensible(proxy),返回一个布尔值。
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
apply(target, object, args) 拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
construct(target, args) 拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
Proxy.revicable()
返回一个可取消的 Proxy 实例。
revoke属性是一个函数,可以取消Proxy实例。当执行revoke函数之后,再访问Proxy实例,会抛出错误。(即:let {proxy, revoke} = Proxy.revocable(target, handler))