// ** 运算符
console.log(2 ** 3); // 8
console.log(3 ** 2); // 9
console.log(10 ** -1); // 0.1
// 右结合
console.log(2 ** 3 ** 2); // 512 (= 2 ** (3 ** 2))
// 赋值运算符
let a = 2;
a **= 3;
console.log(a); // 8
// includes方法
const arr = [1, 2, 3, NaN];
console.log(arr.includes(2)); // true
console.log(arr.includes(4)); // false
console.log(arr.includes(NaN)); // true
// 与indexOf对比
console.log(arr.indexOf(NaN)); // -1(indexOf不能正确处理NaN)
// 从指定位置开始
console.log([1, 2, 3].includes(1, 1)); // false
console.log([1, 2, 3].includes(1, 0)); // true
// async函数
async function fetchData() {
const response = await fetch("/api/data");
const data = await response.json();
return data;
}
// 错误处理
async function safeFetch() {
try {
const data = await fetchData();
return data;
} catch (error) {
console.error(error);
}
}
const obj = { a: 1, b: 2, c: 3 };
// Object.entries
console.log(Object.entries(obj));
// [["a", 1], ["b", 2], ["c", 3]]
// Object.values
console.log(Object.values(obj));
// [1, 2, 3]
// 遍历对象
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
// 转换回对象
const newObj = Object.fromEntries(Object.entries(obj));
// padStart
console.log("5".padStart(3, "0")); // "005"
console.log("abc".padStart(6, "x")); // "xxxabc"
// padEnd
console.log("5".padEnd(3, "0")); // "500"
console.log("abc".padEnd(6, "x")); // "abcxxx"
// 实际应用
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
console.log(`${year}-${month}-${day}`);
const obj = {
name: "东巴文",
get fullName() {
return this.name;
}
};
const descriptors = Object.getOwnPropertyDescriptors(obj);
console.log(descriptors.name);
// {
// value: "东巴文",
// writable: true,
// enumerable: true,
// configurable: true
// }
// 克隆对象(包括getter/setter)
const clone = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
// 允许尾逗号
function foo(
a,
b,
c,
) {
return a + b + c;
}
const arr = [
1,
2,
3,
];
const obj = {
a: 1,
b: 2,
};
// Rest属性
const { a, ...rest } = { a: 1, b: 2, c: 3 };
console.log(a, rest); // 1 { b: 2, c: 3 }
// Spread属性
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, ...obj1 };
console.log(obj2); // { c: 3, a: 1, b: 2 }
// 合并对象
const merged = { ...obj1, ...{ b: 3, d: 4 } };
console.log(merged); // { a: 1, b: 3, d: 4 }
// finally方法
fetch("/api/data")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => {
console.log("请求完成");
hideLoading();
});
// flat扁平化
const arr = [1, [2, [3, [4]]]];
console.log(arr.flat()); // [1, 2, [3, [4]]]
console.log(arr.flat(2)); // [1, 2, 3, [4]]
console.log(arr.flat(Infinity)); // [1, 2, 3, 4]
// flatMap
const arr2 = [1, 2, 3];
const result = arr2.flatMap(x => [x, x * 2]);
console.log(result); // [1, 2, 2, 4, 3, 6]
// 从键值对创建对象
const entries = [["a", 1], ["b", 2]];
const obj = Object.fromEntries(entries);
console.log(obj); // { a: 1, b: 2 }
// Map转对象
const map = new Map([["a", 1], ["b", 2]]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // { a: 1, b: 2 }
// 过滤对象
const original = { a: 1, b: 2, c: 3 };
const filtered = Object.fromEntries(
Object.entries(original).filter(([key, value]) => value > 1)
);
console.log(filtered); // { b: 2, c: 3 }
// 命名捕获组
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = regex.exec("2024-01-15");
console.log(match.groups.year); // "2024"
console.log(match.groups.month); // "01"
console.log(match.groups.day); // "15"
// 后行断言
const str = "东巴文 db-w.cn";
console.log(str.match(/(?<=东巴文 )\S+/)); // ["db-w.cn"]
// 先行断言
console.log(str.match(/\S+(?= db-w.cn)/)); // ["东巴文"]
// dotAll模式
const regex2 = /foo.bar/s;
console.log(regex2.test("foo\nbar")); // true
// flat
console.log([1, [2, [3]]].flat(2)); // [1, 2, 3]
// flatMap
const sentences = ["Hello World", "东巴文"];
const words = sentences.flatMap(s => s.split(" "));
console.log(words); // ["Hello", "World", "东巴文"]
// 已在上面介绍
const str = " hello world ";
console.log(str.trimStart()); // "hello world "
console.log(str.trimEnd()); // " hello world"
console.log(str.trim()); // "hello world"
// 旧写法
try {
doSomething();
} catch (error) {
console.error(error);
}
// 新写法(不需要error参数)
try {
doSomething();
} catch {
console.error("出错了");
}
const sym = Symbol("东巴文");
console.log(sym.description); // "东巴文"
const sym2 = Symbol();
console.log(sym2.description); // undefined
const user = {
name: "东巴文",
address: {
city: "北京"
}
};
// 可选链
console.log(user?.name); // "东巴文"
console.log(user?.address?.city); // "北京"
console.log(user?.phone?.number); // undefined(不报错)
// 函数调用
const obj = {
method: () => "Hello"
};
console.log(obj.method?.()); // "Hello"
console.log(obj.other?.()); // undefined
// 数组访问
const arr = [1, 2, 3];
console.log(arr?.[0]); // 1
console.log(arr?.[10]); // undefined
// ?? 只在null/undefined时使用默认值
const a = null ?? "default"; // "default"
const b = undefined ?? "default"; // "default"
const c = "" ?? "default"; // ""
const d = 0 ?? "default"; // 0
const e = false ?? "default"; // false
// 与||对比
const x = 0 || "default"; // "default"
const y = 0 ?? "default"; // 0
// 结合使用
const value = user?.name ?? "匿名";
// BigInt类型
const big = 9007199254740993n;
console.log(big); // 9007199254740993n
// BigInt函数
const big2 = BigInt(9007199254740993);
console.log(big2); // 9007199254740993n
// 运算
const a = 10n;
const b = 5n;
console.log(a + b); // 15n
console.log(a * b); // 50n
console.log(a / b); // 2n
console.log(a % b); // 0n
// 不能与Number混合运算
// console.log(10n + 5); // TypeError
// 比较
console.log(10n > 5); // true
console.log(10n === 10); // false
console.log(10n == 10); // true
// 统一的全局对象访问
console.log(globalThis);
// 浏览器: window
// Node.js: global
// Worker: self
// 统一使用 globalThis
const str = "test1test2test3";
const regex = /test(\d)/g;
const matches = [...str.matchAll(regex)];
console.log(matches);
// [
// ["test1", "1"],
// ["test2", "2"],
// ["test3", "3"]
// ]
for (const match of str.matchAll(regex)) {
console.log(match[1]);
}
const promises = [
Promise.resolve(1),
Promise.reject("error"),
Promise.resolve(3)
];
Promise.allSettled(promises)
.then(results => {
console.log(results);
// [
// { status: "fulfilled", value: 1 },
// { status: "rejected", reason: "error" },
// { status: "fulfilled", value: 3 }
// ]
});
let a = null;
a ??= "default"; // a = a ?? "default"
console.log(a); // "default"
let b = false;
b ||= true; // b = b || true
console.log(b); // true
let c = { x: 1 };
c &&= c.x; // c = c && c.x
console.log(c); // 1
// 使用下划线分隔数字
const billion = 1_000_000_000;
const bytes = 0xFF_FF_FF_FF;
const bits = 0b1010_0001_1000_0101;
const hex = 0xA0_B0_C0;
console.log(billion); // 1000000000
const str = "东巴文 东巴文 东巴文";
// replace只替换第一个
console.log(str.replace("东巴文", "db-w.cn"));
// "db-w.cn 东巴文 东巴文"
// replaceAll替换所有
console.log(str.replaceAll("东巴文", "db-w.cn"));
// "db-w.cn db-w.cn db-w.cn"
// 使用正则
console.log(str.replaceAll(/东巴文/g, "db-w.cn"));
const promises = [
Promise.reject("error1"),
Promise.resolve("success"),
Promise.reject("error2")
];
Promise.any(promises)
.then(value => console.log(value)) // "success"
.catch(error => console.error(error));
// 全部失败
Promise.any([
Promise.reject("error1"),
Promise.reject("error2")
])
.catch(error => {
console.log(error instanceof AggregateError); // true
console.log(error.errors); // ["error1", "error2"]
});
// WeakRef弱引用
let obj = { name: "东巴文" };
const weakRef = new WeakRef(obj);
console.log(weakRef.deref()); // { name: "东巴文" }
obj = null; // 可以被垃圾回收
// FinalizationRegistry
const registry = new FinalizationRegistry((value) => {
console.log("对象被回收:", value);
});
let target = { data: "test" };
registry.register(target, "target标识");
target = null; // 可能触发回调
class Person {
#name; // 私有字段
constructor(name) {
this.#name = name;
}
get name() {
return this.#name;
}
#privateMethod() {
return "私有方法";
}
}
const person = new Person("东巴文");
console.log(person.name); // "东巴文"
// console.log(person.#name); // SyntaxError
// console.log(person.#privateMethod()); // SyntaxError
class Config {
static settings;
static {
this.settings = {
apiUrl: "https://api.db-w.cn",
timeout: 5000
};
}
}
console.log(Config.settings);
const arr = [1, 2, 3, 4, 5];
console.log(arr.at(0)); // 1
console.log(arr.at(-1)); // 5(最后一个元素)
console.log(arr.at(-2)); // 4
// 等价于
console.log(arr[arr.length - 1]); // 5
const obj = { a: 1 };
console.log(Object.hasOwn(obj, "a")); // true
console.log(Object.hasOwn(obj, "b")); // false
console.log(Object.hasOwn(obj, "toString")); // false
// 比 hasOwnProperty 更安全
const obj2 = Object.create(null);
obj2.a = 1;
// obj2.hasOwnProperty("a"); // TypeError
console.log(Object.hasOwn(obj2, "a")); // true
const arr = [1, 2, 3, 4, 3, 2, 1];
// findLast
console.log(arr.findLast(x => x > 2)); // 3
console.log(arr.findLastIndex(x => x > 2)); // 4
// toSorted/toReversed/toSpliced(不修改原数组)
const sorted = arr.toSorted();
console.log(sorted); // [1, 1, 2, 2, 3, 3, 4]
console.log(arr); // 原数组不变
const reversed = arr.toReversed();
console.log(reversed); // [1, 2, 3, 4, 3, 2, 1]
const spliced = arr.toSpliced(2, 2, "a", "b");
console.log(spliced); // [1, 2, "a", "b", 3, 2, 1]
// with(替换指定索引)
const replaced = arr.with(2, "新值");
console.log(replaced); // [1, 2, "新值", 4, 3, 2, 1]
掌握了ES7-ES12特性后,让我们继续学习:
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文寄语:JavaScript每年都会发布新特性,可选链、空值合并、BigInt等特性已经广泛使用。保持学习新特性是前端开发者的必备技能。在 db-w.cn,我们帮你紧跟JavaScript发展!