Object
assign(target, ...sources),复制sources的自有可枚举属性到target,并返回target,复制过程用的是sources的[[Get]]与target的[[Set]];create(proto, propertiesObject),使用指定的原型对象和自有可枚举属性创建一个新对象;defineProperty(target, propName, descriptor),给target添加或修改名为propName的属性,并指定属性描述符;entries(target)返回target的自有可枚举属性的键值对数组,形如[ ['propA', '1'], ['propB', 2] ];keys(target)返回target的自有可枚举属性的名称数组,形如['propA', 'propB'];values(target)返回target的自有可枚举属性的值数组,形如['1', '2'];preventExtensions(target)将target变为不可扩展;freeze(target)冻结target;seal(target)密封target;is(a, b)比较a和b是否相等;isExtensible(target),对象是否可扩展,frozen或sealed对象都不可扩展;isFrozen(target),对象是否已冻结;isSealed(target),对象是否已密封;getOwnPropertyDescriptor(target, propName)返回指定属性名的descriptor;getOwnPropertyNames(target)返回string类型的自有属性名数组,无关属性是否可枚举;getOwnPropertySymbols(target)返回symbol类型的自有属性名数组,无关属性是否可枚举;getPrototypeOf(target)返回target的原型对象;setPrototypeOf(target, prototype)将target的原型对象设为prototype;- fromEntries
prototype.hasOwnProperty(propName),实例是否具有指定属性;prototype.isPrototypeOf(target),实例是否在target的原型链上;prototype.propertyIsEnumerable(propName),实例的propName属性是否是可枚举的;
注1:可借助new Map(Object.entries())快速便捷地构造一个Map;
注2:带有OwnProperty的方法,操作的都是自有属性;
注3:
- 不可扩展(non-extensible):不能再添加新属性;
- 密封(sealed):不能再添加新属性,已有属性标记为不可配置;
- 冻结(frozen):不能再添加新属性,已有属性标记为不可配置,属性值不可写;
注4:is()不同于==:is不做强制转换;is()不同于===:is认为NaN等于NaN,+0不等于-0;
注5:Object.prototype, window, location的原型都是不可变的,无法通过setPrototypeOf修改;
Function
arguments,函数实参组成的类数组对象;length,函数形参数量,不包括剩余参数和有默认值的参数;prototype.bind(thisArg,arg1, arg2, ...),返回一个新函数,调用新函数时将this指向thisArg,并将arg1,arg2等作为参数传入新函数;prototype.call(thisArg, arg1, arg2, ...),调用函数,将this指向thisArg,将arg1,arg2等作为参数传入;prototype.apply(thisArg,argsArray),调用函数,将this指向thisArg,以数组或类数组形式传入参数argsArray;- Symbol
for(key)找到并返回全局symbol表中键为key的symbol,若不存在则新建一个再返回;keyFor(sym)找到并返回全局symbol表中sym的key;- 其他还包含各种内置对象的方法名的Symbol版本,它们各自标识的方法或属性,将被内置对象的方法调用时(此处断句)调用,例如
obj的自定义方法obj[Symbol.split] = function () {...}会被String.prototype.split(obj)调用,简单来说,某些Symbol版本的方法将覆盖同名方法;
注:new Function("...")只能创建全局作用域下的函数,函数内只能访问全局作用域或自身作用域,即使被封装进某个function funcA,也无法访问到funcA的作用域,例如:
var x = 10;
function createFunction1() {
var x = 20;
return new Function('return x;'); // 这里的 x 指向最上面全局作用域内的 x
}
Array
prototype.at(index),返回index索引处的元素;prototype.indexOf(item),按索引的低到高顺序,查找并返回指定数组元素的索引;prototype.lastIndexOf(item),按索引的高到低顺序,查找并返回指定数组元素的索引;prototype.find((element, index) => {}),按索引的低到高顺序,返回第一个使给定函数返回true的元素;prototype.findIndex((element, index) => {}),按索引的低到高顺序,返回第一个使给定函数返回true的元素索引;prototype.findLast((element, index) => {}),按索引的高到低顺序,返回第一个使给定函数返回true的元素;prototype.findLastIndex((element, index) => {}),按索引的高到低顺序,返回第一个使给定函数返回true的元素索引;prototype.fill(item, start, end),修改原数组,从start(包含start)到end的元素被填充为item;prototype.concat(arr1,arr2,...),返回实例与参数合并后的新数组,无参数则返回一个实例的浅拷贝;prototype.every((element, index) => {}),每个数组元素都会调用给定函数,返回值都为true,则该方法返回true;prototype.some((element, index) => {}),每个数组元素都会调用给定函数,返回值有一个为true,则该方法返回true;prototype.includes(searchElement, fromIndex),从fromIndex开始查找,如果数组中存在searchElement,则返回true;prototype.sort((a,b)=>{}),原地操作,调用给定函数,按返回值排序(大于0则b在前,小于0则a在前),没有给定函数,则该方法将元素按Unicode字符序排序;prototype.splice(start, deleteCount, item1, ...),修改原数组,从start开始(不包含start),删除deleteCount个元素,填入item1等参数;prototype.slice(start, end),不修改原数组,返回从start到end(不包含end)的子数组;prototype.filter((element, index) => {}),每个数组元素都会调用给定函数,返回使给定函数为true的元素组成的子数组;prototype.map((element, index) => {}),每个数组元素都会调用给定函数,返回以给定函数返回值为元素的新数组;prototype.push(item1, ...),将参数添加到数组尾;prototype.pop(),删除并返回尾元素;prototype.unshift(item1, ...),将参数添加到数组头;prototype.shift(),删除并返回首元素;prototype.reverse(),颠倒数组元素;prototype.flat(depth),将嵌套深度为depth的数组元素提取到一维数组中并返回这个新数组;prototype.reduce((pre, cur, curInx), initialValue),调用给定函数将元素减少到一个,initialValue有值,则初始时,pre取initialValue,cur取第一个,否则初始时pre取第一个,cur取第二个,初始执行后,给定函数返回值作pre,下一个元素做cur;prototype.join(separator),返回以separator连接起来的所有元素组成的字符串;
String
字符串是不可变值,下面这些方法都返回新字符串,不会修改原串:
length,UTF-16 码元个数,emoji 等代理对会计为 2,按字符计数要用[...str].length;prototype.at(index),返回指定索引的字符,支持负索引;prototype.charAt(index),返回指定索引的字符,越界返回空串;prototype.charCodeAt(index),返回 UTF-16 码元;prototype.codePointAt(index),返回完整码点,能正确处理 emoji;prototype.indexOf(search, fromIndex)/lastIndexOf,查找子串位置,找不到返回 -1;prototype.includes(search, position),是否包含子串;prototype.startsWith(search, position)/endsWith(search, length),是否以指定子串开头/结尾;prototype.slice(start, end),支持负索引,不修改原串;prototype.substring(start, end),会自动交换起止、负数按 0 处理,行为不如 slice 直观,不推荐;prototype.split(separator, limit),按字符串或正则分割;分隔符是带捕获组的正则时,捕获组会出现在结果里;prototype.replace(pattern, replacement),pattern 是字符串时只替换第一个;replacement 支持$&、$1、$<name>;prototype.replaceAll(pattern, replacement),全局替换,pattern 是字符串时也替换所有;prototype.match(regexp),不带 g 返回首个匹配及分组,带 g 返回所有匹配(丢失分组);prototype.matchAll(regexp),要求 g,返回迭代器,保留分组与 index;prototype.search(regexp),返回首个匹配的位置,不返回匹配内容;prototype.toUpperCase()/toLowerCase(),大小写转换;受本地化影响时用toLocaleUpperCase;prototype.trim()/trimStart()/trimEnd(),去除两端空白;prototype.padStart(length, pad)/padEnd(length, pad),补全到指定长度;prototype.repeat(count),重复 count 次;prototype.concat(...strs),拼接字符串;prototype.localeCompare(other),按本地化规则比较,返回负数/0/正数;prototype.normalize(form),Unicode 规范化(NFC/NFD 等);String.fromCharCode(...codes)/String.fromCodePoint(...codes),码元/码点转字符串;String.raw,模板字符串标签,保留原始转义;Symbol.iterator,字符串可迭代,for...of按码点遍历,[...str]能正确拆分 emoji。
注:replace / match 的正则是否带 g,以及 lastIndex 是否被重置,是实际开发中最容易踩的两个坑。
Promise
Promise 是一个状态机,状态只能从 pending 变为 fulfilled 或 rejected,落定后不可逆:
then(onFulfilled, onRejected),返回一个新 Promise,回调的返回值会被包装;抛错会传给下一个catch;catch(onRejected),等价于then(undefined, onRejected);finally(onFinally),无论成功失败都执行,回调不接收参数,也不改变原值;Promise.resolve(value),把值包装成 fulfilled 的 Promise;传入 Promise 时原样返回;Promise.reject(reason),返回 rejected 的 Promise;Promise.all(iterable),全部成功才成功,结果为数组;任意一个失败立即 reject(fail-fast);Promise.allSettled(iterable),等待全部落定,返回{ status, value | reason }数组,不会 reject;Promise.race(iterable),第一个落定的结果(成功或失败)就是结果;Promise.any(iterable),第一个成功的;全部失败时抛AggregateError;Promise.withResolvers()(ES2024),一次性拿到{ promise, resolve, reject },适合把回调式 API 包成 Promise;then的回调总是异步执行(microtask),一定晚于当前同步代码;async函数返回 Promise;await等价于then,try/catch能捕获 rejected;- 未处理的 rejection 会触发
unhandledrejection,生产环境要统一兜底。
// 并发请求:全部成功才继续
const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
// 只要有一个成功就够
const first = await Promise.any([mirrorA(), mirrorB()]);
// 带并发上限的 map
async function mapLimit(items, limit, fn) {
const results = [];
let i = 0;
const workers = Array.from({ length: limit }, async () => {
while (i < items.length) {
const index = i++;
results[index] = await fn(items[index], index);
}
});
await Promise.all(workers);
return results;
}
RegExp
- 字面量
/pattern/flags,或new RegExp(pattern, flags);需要动态拼接时用后者,注意字符串里的反斜杠要二次转义; - flags:
g:全局匹配,配合lastIndex循环;i:忽略大小写;m:多行,^/$匹配每行首尾;s:dotAll,.匹配换行;u:Unicode 模式,按码点处理,\p{...}需要它;y:sticky,从lastIndex精确开始匹配;d:记录匹配的起止索引(ES2022);
- 实例属性:
source、flags、global、ignoreCase、multiline、unicode、sticky、lastIndex; test(str),返回布尔值;g模式下会推进lastIndex;exec(str),返回匹配数组(含 index、input、groups),g模式下每次返回下一个匹配,匹配完返回 null 并把lastIndex归零;- 字符串侧:
match、matchAll、replace、replaceAll、search、split; - 分组:
()捕获组、(?:...)非捕获、(?<name>...)命名组,结果里通过groups.name取; - 断言:
^、$、\b、\B、(?=...)先行、(?!...)负先行、(?<=...)后行、(?<!...)负后行; - 量词默认贪婪(
*+?{m,n}),加?变惰性,例如.*?; - 字符类:
\d\D\w\W\s\S、[abc]、[^abc]、.; - 常用替换:
$&整个匹配、$`匹配前、$'匹配后、$1分组、$<name>命名分组。
// 千分位
const format = (n) => String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// 命名分组 + matchAll
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g;
for (const m of "2026-10-22".matchAll(re)) {
console.log(m.groups.year, m.groups.month, m.groups.day);
}
注:g 正则是有状态的,同一个正则对象在 test / exec 之间混用,很容易出现“第一次 true,第二次 false”的问题;要么每次新建,要么手动把 re.lastIndex 归零。
End of entry