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