<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>前端笔记</title>
	<atom:link href="https://www.hu365.dev/blog/category/frontend/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.hu365.dev</link>
	<description>Justin Woo（吴晓虎）的个人博客，生命不息，学习不止</description>
	<lastBuildDate>Sun, 18 Feb 2024 01:35:05 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.3</generator>

<image>
	<url>https://www.hu365.dev/wp-content/uploads/2022/10/cropped-logo-正矩形.blue_-32x32.png</url>
	<title>前端笔记</title>
	<link>https://www.hu365.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>webstorm的代理设置</title>
		<link>https://www.hu365.dev/blog/2023/02/301/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Sun, 05 Feb 2023 00:47:00 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[JetBrains]]></category>
		<category><![CDATA[Webstorm]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=301</guid>

					<description><![CDATA[一：自身代理配置 官方文档：HTTP Proxy &#124; WebStorm Documentation (jetbrains.com)影响插件、工具下载等常用请求 二：Git代理配置 影响代码仓库的拉取、推送及git的其他请求 三：Npm代理配置 影响npm下载、 <a href="https://www.hu365.dev/blog/2023/02/301/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">一：自身代理配置</h2>



<p>官方文档：<a href="https://www.jetbrains.com/help/webstorm/settings-http-proxy.html">HTTP Proxy | WebStorm Documentation (jetbrains.com)</a><br>影响插件、工具下载等常用请求</p>



<h2 class="wp-block-heading">二：Git代理配置</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#设置全局代理
git config --global http.proxy http://127.0.0.1:10811
git config --global https.proxy https://127.0.0.1:10811
git config --global http.proxy socks5://127.0.0.1:10810
git config --global https.proxy socks5://127.0.0.1:10810

#只对github.com使用代理，其他仓库不走代理
git config --global http.https://github.com.proxy socks5://127.0.0.1:10810
git config --global https.https://github.com.proxy socks5://127.0.0.1:10810
#取消github代理
git config --global --unset http.https://github.com.proxy
git config --global --unset https.https://github.com.proxy

#取消全局代理
git config --global --unset http.proxy
git config --global --unset https.proxy</pre>



<p>影响代码仓库的拉取、推送及<code>git</code>的其他请求</p>



<h2 class="wp-block-heading">三：Npm代理配置</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#直接代理
npm config set proxy http://127.0.0.1:18011
npm config set https-proxy https://127.0.0.1:18011

#授权代理
npm config set proxy http://username:password@127.0.0.1:18011
npm config set https-proxy https://username:password@127.0.0.1:18011

#取消代理
npm config delete proxy
npm config delete https-proxy</pre>



<p>影响<code>npm</code>下载、推送等</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>在wordpress页面中嵌入React页面应用</title>
		<link>https://www.hu365.dev/blog/2022/12/215/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Mon, 19 Dec 2022 12:05:22 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=215</guid>

					<description><![CDATA[想实现一个“技术题库”的专栏，用来收藏一些经典题型、不太熟悉的面试题/技术题，采局部React应用的方式实现 一：XAMPP环境 本地启用wordpress，还原现网主题与配置，启用本地测试域名 1.1：本地wordpress XAMPP是免费的集成安装包（下 <a href="https://www.hu365.dev/blog/2022/12/215/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<p>想实现一个“技术题库”的专栏，用来收藏一些经典题型、不太熟悉的面试题/技术题，采局部<code>React</code>应用的方式实现</p>



<h2 class="wp-block-heading">一：XAMPP环境</h2>



<p>本地启用<code>wordpress</code>，还原现网主题与配置，启用本地测试域名</p>



<h3 class="wp-block-heading">1.1：本地wordpress</h3>



<p><code>XAMPP</code>是免费的集成安装包（<a href="https://www.apachefriends.org/">下载地址</a>），集成了<code>Apache</code>、<code>php8</code>、<code>mysql</code>、<code>phpMyAdmin</code></p>



<ul>
<li>下载<code>wordpress</code>解压到自己想要放的位置，我选择在<code>/xampp/apps/www.hu365.test</code></li>



<li>把线上使用的<code>主题</code>完整下载并在本地主题使用</li>



<li>通过<code>phpMyAdmin</code>，创建数据库并导入线上的备份数据</li>



<li>配置<code>xampp/apache/conf/extra/httpd-vhosts.conf</code>文件，添加本地测试域名：<code>www.hu365.test</code></li>



<li>本地<code>host</code>文件，将<code>www.hu365.test</code>指向<code>127.0.0.1</code></li>
</ul>



<p>此时，就可以通过<code>www.hu365.test</code>访问和线上环境一样的页面了</p>



<h3 class="wp-block-heading">1.2：wordpress页面</h3>



<p>新建页面<code>技术题库</code>，使用<code>代码编辑器</code>，引入最新的<code>react.js</code>、以及生产<code>js</code>、<code>css</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;!-- 所有额外引入的js、css -->
&lt;div>
	&lt;script src="/wp-content/apps/topic-bank/static/js/react.production.min.js" crossorigin>&lt;/script>
	&lt;script src="/wp-content/apps/topic-bank/static/js/react-dom.production.min.js" crossorigin>&lt;/script>
	&lt;script defer="defer" src="/wp-content/apps/topic-bank/static/js/main.js">&lt;/script>
	&lt;link href="/wp-content/apps/topic-bank/static/css/main.css" rel="stylesheet">
&lt;/div>
&lt;!-- 这是react渲染节点 -->
&lt;div id="react_root">&lt;/div></pre>



<ul>
<li>这里有进行<code>格式化</code>排版，实际代码为了减少多余换行，去掉了所有换行与空格</li>



<li>引入路径都是用<code>绝对路径</code>引入</li>



<li>路径<code>/wp-content/apps/topic-bank</code>是<code>react</code>指定的生产目录</li>



<li><code>main.js</code>、<code>main.css</code>为生产环境<code>不含hash</code>的最终文件，此举是为了测试，异步加载主<code>js</code></li>



<li>页面访问路径（<code>URL</code>），需在路由配置中配置为<code>basename</code>，此处配置为<code>/topic-bank</code></li>
</ul>



<h2 class="wp-block-heading">二：React应用</h2>



<p>使用<code>create-react-app</code>构建<code>react app</code>，配置生产文件名、生产路径、静态资源等</p>



<h3 class="wp-block-heading">2.1：替换index.html</h3>



<p>访问本地页面：技术题库，右键另存为页面得到<code>index.html</code>页面和资源文件夹</p>



<ul>
<li>把资源文件夹重命名：<code>static</code>，并在<code>static</code>下新建文件夹：<code>js</code>、<code>css</code></li>



<li><code>js</code>文件移动到<code>js</code>文件夹，<code>css</code>文件移动到<code>css</code>文件夹，并同步修改相关引用路径</li>



<li>下载<code>react.production.min.js</code>、<code>react-dom.production.min.js</code>到<code>js</code>文件夹</li>
</ul>



<p>此举是为了实现测试环境的样式和线上相同，方便直接使用<code>react</code>进行调试开始</p>



<h3 class="wp-block-heading">2.2：生产配置</h3>



<p>因为<code>create-react-app</code>构建应用无法直接修改webpack，这里需要安装使用<code>react-app-rewired</code>，可以同步安装<code>customize-cra</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install react-app-rewired --save-dev</pre>



<p>创建文件<code>config-overrides.js</code>，在其中修改配置：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">module.exports = function override(config, env) {
	// 仅修改生产配置
	if (env !== 'production') return config;
	const paths = require('react-scripts/config/paths');

	// 额外引入的
	// react.production.min.js、react-dom.production.min.js
	// 不参与打包
	config.externals = {
		'react': 'React',
		'react-dom': 'ReactDOM',
	}

	// 生产输出目录
	// 与"页面"中路径一致：/wp-content/apps/topic-bank
	config.output.path = "C:/xampp/apps/www.hu365.dev/wp-content/apps/topic-bank";
	paths.appBuild = "C:/xampp/apps/www.hu365.dev/wp-content/apps/topic-bank";

	// Get rid of hash for js files
	// 方便测试，脚本文件去除hash
	config.output.filename = "static/js/[name].js";
	config.output.chunkFilename = "static/js/[name].chunk.js";

	// Get rid of hash for css files
	// 方便测试，样式文件去除hash
	const miniCssExtractPlugin = config.plugins.find(element => element.constructor.name === "MiniCssExtractPlugin");
	miniCssExtractPlugin.options.filename = "static/css/[name].css";
	miniCssExtractPlugin.options.chunkFilename = "static/css/[name].css";

	// Get rid of hash for media files
	// 方便测试，其他文件去除hash
	config.module.rules[1].oneOf.forEach(oneOf => {
		if (!oneOf.options || oneOf.options.name !== "static/media/[name].[hash:8].[ext]") {
			return;
		}
		oneOf.options.name = "static/media/[name].[ext]";
	});
	return config;
}</pre>



<h3 class="wp-block-heading">2.3：添加路由</h3>



<p>新建<code>router/index.tsx</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 列表页、和详情页
import TopicList from "../views/TopicList";
import TopicContent from "../views/TopicContent";
import {
	createBrowserRouter,
	RouterProvider,
} from "react-router-dom";

const router = createBrowserRouter([
	{
		path: "/",
		element: &lt;TopicList />,
	},
	{
		path: "/topicName",
		element: &lt;TopicContent />,
	},
], {
	// 通过环境变量配置基础路径
	basename: process.env.REACT_APP_ROUTER_BASE_NAME
});

export default function Router() {
	return (
		&lt;RouterProvider router={router} />
	)
}</pre>



<p>环境变量配置：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 测试环境：.env.development
// 随意填写
REACT_APP_ROUTER_BASE_NAME = /

// 生产环境：.env.production
// 该路径必须和"页面"访问URL相同，否则无法访问（/topic-bank）
REACT_APP_ROUTER_BASE_NAME = /topic-bank</pre>



<h3 class="wp-block-heading">2.4：配置别名</h3>



<p>正在开发中，忽然发现<code>../../*</code>的书写格式还是太丑了，赶紧把别名加上<br><code>webpack</code>的<code>alias</code>配置，同样在<code>config-override.js</code>中配置：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const path = require("node:path");

module.exports = function override(config, env) {
    // 相对路径别名
    config.resolve.alias = {
        '@': path.resolve(__dirname, 'src'),
        '@Pages': path.resolve(__dirname, 'src/pages'),
        '@Style': path.resolve(__dirname, 'src/style'),
        '@Components': path.resolve(__dirname, 'src/components'),
    };

    // 其他内容
    
    return config;
}</pre>



<p><code>TS</code>配置，<code>tsconfig.json</code>文件：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
  "compilerOptions": {
    ...
    "paths": {
      "@/*": ["./*"],
      "@Pages/*": ["./pages/*"],
      "@Style/*": ["./style/*"],
      "@Components/*": ["./components/*"]
    }
  },
  ...
}
</pre>



<h2 class="wp-block-heading">三：开发中</h2>



<p>完成以上工作后，启动测试服务，访问的页面和线上“技术题库”页面样式一致<br>这样就可以脱离<code>wordpress</code>进行本地开发<br>待到一定阶段，需要看最终效果时；直接<code>build</code>一下，再在本地环境访问“技术题库”即可</p>



<p>好了，可以开始接下来开发工作了！</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>记录jsPdf相关使用</title>
		<link>https://www.hu365.dev/blog/2022/11/184/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Wed, 30 Nov 2022 13:37:30 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[html2canvas]]></category>
		<category><![CDATA[JAVASCRIPT]]></category>
		<category><![CDATA[jsPDF]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=184</guid>

					<description><![CDATA[相关文档： 一：我的需求 浏览器接口：window.print()，可以直接调用打印，并存储为PDF文档用工具库：html2canvas+jsPDF实现以上（类似的）PDF 二：我的实现 2.1：基础参数 首先定义一个标准数据，以Windows下的A4打印为基 <a href="https://www.hu365.dev/blog/2022/11/184/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<p>相关文档：</p>



<ul>
<li><a href="https://artskydj.github.io/jsPDF/docs/jsPDF.html">jsPDF &#8211; Documentation (artskydj.github.io)</a></li>



<li><a href="https://html2canvas.hertzen.com/configuration">Options &#8211; html2canvas (hertzen.com)</a></li>
</ul>



<h2 class="wp-block-heading">一：我的需求</h2>



<p>浏览器接口：<code>window.print()</code>，可以直接调用打印，并存储为<code>PDF</code>文档<br>用工具库：<code>html2canvas</code>+<code>jsPDF</code>实现以上（类似的）<code>PDF</code></p>



<h2 class="wp-block-heading">二：我的实现</h2>



<h3 class="wp-block-heading">2.1：基础参数</h3>



<p>首先定义一个标准数据，以<code>Windows</code>下的<code>A4</code>打印为基础：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 基础参数
const printParams = {
	a4: {
		dpi: 96, // windows 下默认 dpi
		width: 210, // A4 标准宽度 mm，含边距
		height: 297, // A4 标准高度 mm， 含边距
		marginX: 10, // 默认打印左右边距，约为 10mm
		marginY: 10, // 默认打印上下边距，约为 10mm
	},
	// 以下是设置值/初始值
	dpi: 288, // 设置的打印密度，数值越大越清晰，PDF文件越大
	format: 'a4', // 打印类型，这里只有 A4
	orientation: 'portrait', // portrait | landscape
	// 以下为计算出的值，方便调用
	ratio: 1, // dpi 比例
	width: 0, // PDF 文档宽度，不含边距
	widthFull: 0, // PDF 文档完整宽度
	height: 0, // PDF 文档高度，不含边距
	heightFull: 0, // PDF 文档完整高度
	marginX: 0, // PDF 左右边距
	marginY: 0, // PDF 上下边距
}</pre>



<p>数据初始化：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 根据设置的 dpi，format，orientation 数据初始化
const { dpi: setDpi, orientation, format } = printParams;
const { dpi, width, height, marginX, marginY } = printParams[format];
printParams.ratio = setDpi/dpi;
let setWidth;
switch (orientation) {
	case 'landscape':
		printParams.width = height - 2 * marginY; // 不含边距的内容宽度
		printParams.height = width - 2 * marginX; // 不含边距的内容高度
		printParams.widthFull = height; // 整页PDF宽度
		printParams.heightFull = width; // 整页PDF高度
		printParams.marginX = marginY; // 左右单边边距
		printParams.marginY = marginX; // 上下单边边距
		setWidth = mm2px(height, dpi); // 页面宽度像素值
		break;
	case 'portrait':
	default:
		printParams.width = width - 2 * marginX;
		printParams.height = height - 2 * marginY;
		printParams.widthFull = width;
		printParams.heightFull = height;
		printParams.marginX = marginX;
		printParams.marginY = marginY;
		setWidth = mm2px(width, dpi);
}
// 设置body宽度，给 window.print 一个“最适合”的宽度
window.document.body.style.width = `${setWidth}px`;</pre>



<p>这里有用到一个<code>mm</code>/<code>px</code>的转换，把以前写过的方法拿过来：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/**
 * 工具类：mm转px
 * */
function mm2px(mm, dpi, radio) {
	if (mm == null) return 0;
	dpi = dpi || printParams.dpi;
	const ret = parseFloat(`${(mm * dpi * 10) / 254}`);
	if (radio == null || radio &lt;= 0) radio = 4;
	radio = 10 ** radio;
	return Math.floor(ret * radio) / radio;
}
/**
 * 工具类：px转mm
 * */
function px2mm(px, dpi, radio) {
	if (px == null) return 0;
	dpi = dpi || printParams.dpi;
	const ret = parseFloat(`${(px * 254) / (dpi * 10)}`);
	if (radio == null || radio &lt;= 0) radio = 4;
	radio = 10 ** radio;
	return Math.floor(ret * radio) / radio;
}</pre>



<h3 class="wp-block-heading">2.2：生成图片</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 需要用到的数据
const $pdfDom = document.getElementById('pdf');
const {
	ratio, orientation, format,
	width, height, widthFull, marginX, marginY
} = printParams;

html2canvas($pdfDom, {
	scale: window.devicePixelRatio * Math.ceil(ratio), // 缩放
	allowTaint: true,
	useCORS: true,
}).then((canvas) => {
	const canvasWidth = this.px2mm(canvas.width);
	const canvasHeight = this.px2mm(canvas.height);
	// ··· 以下是 pdf 生成
	// ···
});</pre>



<p>此处用到<code>html2canvas</code>实现绘制页面生成图片，主要影响清晰度的是参数<code>scale</code>：</p>



<figure class="wp-block-table is-style-stripes has-small-font-size"><table><tbody><tr><td width="90">scale</td><td width="280"><code>window.devicePixelRatio</code></td><td>The scale to use for rendering. Defaults to the browsers device pixel ratio.</td></tr></tbody></table></figure>



<p>默认值为<code>window.devicePixelRatio</code>，主要用于防止页面缩放导致的生成图片不清晰问题<br>为了实现更好地缩放，最好乘以一个整数值，以保证像素值的对应，就把它当作<code>windows</code>下的高分屏缩放理解就行</p>



<p>这里用<code>px2mm</code>转换成<code>mm</code>主要方便用于后面的<code>PDF</code>编辑</p>



<h3 class="wp-block-heading">2.3：生成PDF</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 得到图片数据
const pageData = canvas.toDataURL('image/jpeg', 1.0);
// 创建PDF文档对象
const PDF = new JsPDF({ orientation, format });
// 标准宽度下，图片的相对高度
const imageHeight = (width / canvasWidth) * canvasHeight;
// 考虑可能有多页的情况，用 leftHeight 循环判断
let leftHeight = imageHeight;
// 每次绘制图片的位置垂直偏移量
let position = marginY;
while (leftHeight > 0) {
	// 1：图形绘制到PDF
	PDF.addImage(pageData, 'JPEG', marginX, position, width, imageHeight);
	leftHeight -= height;
	position -= height;
	// 2：页头页脚添加，用 rect 遮罩
	PDF.setFillColor(255, 255, 255); // 填充白色，每次填充前都要定义
	PDF.rect(0, 0, widthFull, marginY, 'F');
	PDF.rect(0, height + marginY, widthFull, marginY, 'F');
	// 添加空白页
	if (leftHeight > 0) {
		PDF.addPage();
	}
}
PDF.save(`${title}.pdf`);</pre>



<p>这里有几个点，需要留意：</p>



<ol>
<li>默认PDF为单页，需要判断“图片”相对高度，超出标准高度时添加新页面</li>



<li>每次添加新页面，<code>PDF</code>绘制即“当前页”，相对位置都是相对“当前页”而言</li>



<li>绘制遵循页面标准的层级，后绘制内容会覆盖已绘制内容</li>



<li>垂直偏移<code>position</code>是图片相对“当前页”的偏移，向上偏移一个内容页的距离后，当前页绘制的就是下一页该显示的图片内容</li>



<li>页眉页脚的模拟绘制，每次都要设置填充颜色（默认为黑色），因为每次都是“不同页”，参考第<code>2</code>点</li>
</ol>



<h2 class="wp-block-heading">三：实现效果</h2>



<p>目前只需要模拟<code>A4</code>下的打印，在对比使用<code>window.print()</code>生成的<code>PDF</code>和手动生成的<code>PDF</code>之后，还是比较满意的，以后再有自定义编辑页眉页脚，到时候再说</p>



<figure class="wp-block-image size-large"><a href="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-jpeg.webp"><img data-dominant-color="dbdbdb" data-has-transparency="false" style="--dominant-color: #dbdbdb;" fetchpriority="high" decoding="async" width="1024" height="473" src="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-1024x473.webp" alt="pdf对比" class="not-transparent wp-image-188" srcset="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-1024x473.webp 1024w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-300x138.webp 300w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-768x355.webp 768w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-1536x709.webp 1536w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFavNBJzNCfywOBr7ZJwPYlgDg8gWt8BwAA_2556_1180-2048x945.webp 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">看起来分页和边距都差不多</figcaption></figure>



<figure class="wp-block-image size-large"><a href="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-jpeg.webp"><img data-dominant-color="ededed" data-has-transparency="false" style="--dominant-color: #ededed;" decoding="async" width="1024" height="460" src="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-1024x460.webp" alt="PDF对比" class="not-transparent wp-image-189" srcset="https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-1024x460.webp 1024w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-300x135.webp 300w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-768x345.webp 768w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-1536x690.webp 1536w, https://www.hu365.dev/wp-content/uploads/2022/11/lQLPJxbsCEPoFnLNBHzNCfqwF0k3xKX6TnMDg8gWwgAcAA_2554_1148-2048x921.webp 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">清晰度也还满意</figcaption></figure>



<p>要说有什么不满意的地方，那肯定是哪里不满意再改哪里，哪里不购加哪里<br>不过呢，有个东西肯定只会越改（加）越糟的，那就是文件大小：</p>



<figure class="wp-block-image size-full"><a href="https://www.hu365.dev/wp-content/uploads/2022/11/710AAC88-0F98-42df-8A72-A372AEEE26EA-jpeg.webp"><img data-dominant-color="f5f6f7" data-has-transparency="false" style="--dominant-color: #f5f6f7;" decoding="async" width="983" height="297" src="https://www.hu365.dev/wp-content/uploads/2022/11/710AAC88-0F98-42df-8A72-A372AEEE26EA-jpeg.webp" alt="PDF文件大小对比" class="not-transparent wp-image-190" srcset="https://www.hu365.dev/wp-content/uploads/2022/11/710AAC88-0F98-42df-8A72-A372AEEE26EA-jpeg.webp 983w, https://www.hu365.dev/wp-content/uploads/2022/11/710AAC88-0F98-42df-8A72-A372AEEE26EA-300x91.webp 300w, https://www.hu365.dev/wp-content/uploads/2022/11/710AAC88-0F98-42df-8A72-A372AEEE26EA-768x232.webp 768w" sizes="(max-width: 983px) 100vw, 983px" /></a><figcaption class="wp-element-caption">2081 VS 124</figcaption></figure>



<p>Holy shit，大了整整20倍·····<br>这和生成图片时设置的缩放比（<code>scale</code>）有关，目前我测试时改值为<code>4.5</code>（<code>1.5*288/96</code>），既使变成<code>1/5</code>也还有400KB，大约4倍的差距，看来文件大小的劣势还是挺明显的</p>



<p>不过呢，现在谁还在乎这么点大小呢···谁还在乎呢···谁···</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>全局变量 window.status</title>
		<link>https://www.hu365.dev/blog/2022/11/181/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Sat, 26 Nov 2022 10:28:00 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[JAVASCRIPT]]></category>
		<category><![CDATA[status]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=181</guid>

					<description><![CDATA[参考资料： 在使用apiCloud编写手机App的项目里，有部分使用纯原生js实现的功能，在这里调试的时候，我遇到了一个奇怪的问题，简单地说，他是这样的： 我的本意是打算把'111'和'222'当作参数来处理的，但是结果却超出我的预料它居然循环出了：'1' ' <a href="https://www.hu365.dev/blog/2022/11/181/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<p>参考资料：</p>



<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/status">Window.status &#8211; Web APIs | MDN (mozilla.org)</a></li>
</ul>



<p>在使用<code>apiCloud</code>编写手机<code>App</code>的项目里，有部分使用纯原生<code>js</code>实现的功能，在这里调试的时候，我遇到了一个奇怪的问题，简单地说，他是这样的：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var status = ['111', '222'];
for (var i = 0;i &lt; status.length;i++) {
	// 处理数据
	console.log(status[i]); // 1 1 1 , 2 2 2
}</pre>



<p>我的本意是打算把<code>'111'</code>和<code>'222'</code>当作参数来处理的，但是结果却超出我的预料<br>它居然循环出了：<code>'1' '1' '1' ',' '2' '2' '2'</code>总计<code>6</code>个参数</p>



<p>看结构，它似乎是对处理的数组进行了字符串转换，但是我并没有做此操作<br>第一想法，是不是<code>appCloud</code>哪里做了特殊处理，毕竟这是在它家的平台运行，但是并没有找到相关处理</p>



<p>在寻人讨论的时候，他说了一句：你在浏览器调试试试，看有没有这个问题<br>听到这话的我，内心其实是抗拒的，这么简单的代码，看一眼就知道结果，还要跑去浏览器去调试？那不是多此一举么</p>



<p>然后我就被打脸了，浏览器的调试工具输出了一样的结果···</p>



<p>这···这···最基础的调试方法狠狠的打了一耳光</p>



<p>所以再仔细分析问题，把<code>var</code>换成<code>let</code>/<code>const</code>，打印结果如预期</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const status = ['111', '222'];
for (var i = 0;i &lt; status.length;i++) {
	// 处理数据
	console.log(status[i]); // 111 222
}</pre>



<p>那么用<code>var</code>的问题，自然是全局变量的问题，那对应的全局变量就是：<code>window.status</code></p>



<p>一个早期用来显示浏览器加载状态的文本信息字段，只能用来存储<code>String</code>类型，所以用<code>var</code>定义时，实际上是在给<code>window.status</code>赋值，而且它会自动将数据进行字符串转换</p>



<p>那么，记录这次经历不是为了记下这个将被废弃的属性，而是要让自己了解到，查找问题、解决问题的思路与逻辑，一定要一丝不苟，容不得“想当然”的跳过</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>clipboard.js 与 Vue</title>
		<link>https://www.hu365.dev/blog/2022/08/134/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Sun, 21 Aug 2022 12:27:00 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[Clipboard]]></category>
		<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=134</guid>

					<description><![CDATA[相关参考资料： zenorocha/clipboard.js: Modern copy to clipboard. No Flash. Just 3kb gzipped (github.com) Clipboard.js 一个专职于“复制文本”操作的 js 库 <a href="https://www.hu365.dev/blog/2022/08/134/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<p>相关参考资料：</p>



<ol><li><a href="https://github.com/zenorocha/clipboard.js">zenorocha/clipboard.js: Modern copy to clipboard. No Flash. Just 3kb gzipped (github.com)</a></li></ol>



<h2 class="wp-block-heading">Clipboard.js</h2>



<p>一个专职于“复制文本”操作的 <code>js</code> 库，以其短小精悍、简单实用的功能而被广泛应用</p>



<p>写这边文章的目的是为了说明：<code>Clipboard.js</code>的事件绑定存在直接绑定和事件委托两种方式</p>



<p>其实官网有说明使用方法和注意事项，不过鉴于以前没用过这个库，我并没有第一时间去看文档，反而是看过源码之后才发现文档里面居然已经写明了：</p>



<figure class="wp-block-image size-full"><a href="https://www.hu365.dev/wp-content/uploads/2022/10/image-2.webp"><img data-dominant-color="2c2f37" data-has-transparency="false" style="--dominant-color: #2c2f37;" loading="lazy" decoding="async" width="868" height="280" src="https://www.hu365.dev/wp-content/uploads/2022/10/image-2.webp" alt="" class="not-transparent wp-image-152" srcset="https://www.hu365.dev/wp-content/uploads/2022/10/image-2.webp 868w, https://www.hu365.dev/wp-content/uploads/2022/10/image-2-300x97.webp 300w, https://www.hu365.dev/wp-content/uploads/2022/10/image-2-768x248.webp 768w" sizes="(max-width: 868px) 100vw, 868px" /></a></figure>



<p>所以，看文档的好习惯，还是不能丢了···，那下面纯粹记录一下<code>bug</code>解决过程</p>



<h2 class="wp-block-heading">一：Bug 描述</h2>



<p>维护一个<code>Vue2</code>+<code>Element</code>的项目，调用<code>Clipboard.js</code>初始化的复制按钮；页面第一次进入后点击正常，后续退出、再进入，每次点击会累计多触发一次</p>



<figure class="wp-block-image size-full"><a href="https://www.hu365.dev/wp-content/uploads/2022/10/image.webp"><img data-dominant-color="d8ddd7" data-has-transparency="false" style="--dominant-color: #d8ddd7;" loading="lazy" decoding="async" width="448" height="209" src="https://www.hu365.dev/wp-content/uploads/2022/10/image.webp" alt="" class="not-transparent wp-image-154" srcset="https://www.hu365.dev/wp-content/uploads/2022/10/image.webp 448w, https://www.hu365.dev/wp-content/uploads/2022/10/image-300x140.webp 300w" sizes="(max-width: 448px) 100vw, 448px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://www.hu365.dev/wp-content/uploads/2022/10/image-1.webp"><img data-dominant-color="dfe4dd" data-has-transparency="false" style="--dominant-color: #dfe4dd;" loading="lazy" decoding="async" width="459" height="281" src="https://www.hu365.dev/wp-content/uploads/2022/10/image-1.webp" alt="" class="not-transparent wp-image-153" srcset="https://www.hu365.dev/wp-content/uploads/2022/10/image-1.webp 459w, https://www.hu365.dev/wp-content/uploads/2022/10/image-1-300x184.webp 300w" sizes="(max-width: 459px) 100vw, 459px" /></a></figure>



<p>看看初始化是怎么写的：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">if (!this.jsonClipboard) {
    this.jsonClipboard = new Clipboard('.json-btn');
    this.jsonClipboard.on('success', (e) => {
        this.$message.success('复制成功');
    })
}</pre>



<p>这么写好像没问题；保证每次进入页面只初始化一次<br>而且每次页面进入，<code>dom</code>都是重新生成，不存在重复绑定同一个<code>dom</code>的情况</p>



<p>难道，他绑定的事件不是绑定在按钮<code>dom</code>？</p>



<h2 class="wp-block-heading">二：源码查阅</h2>



<p>GitHub：<a href="https://github.com/zenorocha/clipboard.js">zenorocha/clipboard.js: Modern copy to clipboard. No Flash. Just 3kb gzipped (github.com)</a><br>文件：<code>/src/clipboard.js</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// https://github.com/zenorocha/clipboard.js/blob/master/src/clipboard.js#L22
/**
 * Base class which takes one or more elements, adds event listeners to them,
 * and instantiates a new `ClipboardAction` on each click.
 */
class Clipboard extends Emitter {
    /**
     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
     * @param {Object} options
     */
    constructor(trigger, options) {
        super();

        this.resolveOptions(options);
        this.listenClick(trigger); // 事件监听
    }

    // ...
    // 此处省略 1w 字
    // ...
    
    // https://github.com/zenorocha/clipboard.js/blob/master/src/clipboard.js#L58
    /**
     * Adds a click event listener to the passed trigger.
     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
     */
    listenClick(trigger) {
        this.listener = listen(trigger, 'click', (e) => this.onClick(e));
    }

    // ...
    // 此处省略 1w 字
    // ...
} </pre>



<p><code>listen</code>方法来自于组件<code>good-listener</code>，出自他自己之手<br>GitHub：<a href="https://github.com/zenorocha/good-listener">zenorocha/good-listener: A more versatile way of adding &amp; removing event listeners (github.com)</a><br>文件：<code>/<a href="https://github.com/zenorocha/good-listener/tree/master/src">src</a>/listen.js</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// https://github.com/zenorocha/good-listener/blob/master/src/listen.js#L4
/**
 * Validates all params and calls the right
 * listener function based on its target type.
 *
 * @param {String|HTMLElement|HTMLCollection|NodeList} target
 * @param {String} type
 * @param {Function} callback
 * @return {Object}
 */
function listen(target, type, callback) {
    if (!target &amp;&amp; !type &amp;&amp; !callback) {
        throw new Error("Missing required arguments");
    }

    if (!is.string(type)) {
        throw new TypeError("Second argument must be a String");
    }

    if (!is.fn(callback)) {
        throw new TypeError("Third argument must be a Function");
    }

    if (is.node(target)) {
        return listenNode(target, type, callback);
    } else if (is.nodeList(target)) {
        return listenNodeList(target, type, callback);
    } else if (is.string(target)) {
        return listenSelector(target, type, callback);
    } else {
        throw new TypeError(
            "First argument must be a String, HTMLElement, HTMLCollection, or NodeList"
        );
    }
}

/**
 * Adds an event listener to a HTML element
 * and returns a remove listener function.
 *
 * @param {HTMLElement} node
 * @param {String} type
 * @param {Function} callback
 * @return {Object}
 */
function listenNode(node, type, callback) {
    node.addEventListener(type, callback);

    return {
        destroy: function() {
            node.removeEventListener(type, callback);
        }
    }
}

/**
 * Add an event listener to a list of HTML elements
 * and returns a remove listener function.
 *
 * @param {NodeList|HTMLCollection} nodeList
 * @param {String} type
 * @param {Function} callback
 * @return {Object}
 */
function listenNodeList(nodeList, type, callback) {
    Array.prototype.forEach.call(nodeList, function(node) {
        node.addEventListener(type, callback);
    });

    return {
        destroy: function() {
            Array.prototype.forEach.call(nodeList, function(node) {
                node.removeEventListener(type, callback);
            });
        }
    }
}

/**
 * Add an event listener to a selector
 * and returns a remove listener function.
 *
 * @param {String} selector
 * @param {String} type
 * @param {Function} callback
 * @return {Object}
 */
function listenSelector(selector, type, callback) {
    return delegate(document.body, selector, type, callback);
}
</pre>



<p>这里这哥们又调用了一个自己的库：<code>delegate</code><br>Github：<a href="https://github.com/zenorocha/delegate">zenorocha/delegate: Lightweight event delegation (github.com)</a></p>



<h2 class="wp-block-heading">三：解决方案</h2>



<p>从上面的源码已经很清楚：<br>参数为<code>node</code>、<code>nodeList</code>时，直接使用<code>addEventListener</code>进行事件绑定；<br>参数为字符串时，会用事件委托实现选择器可能的所有<code>dom</code>的操作事件</p>



<p>而出现<code>bug</code>的原因自然是：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 此处使用类选择器 .json-btn
this.jsonClipboard = new Clipboard('.json-btn');</pre>



<p>所以在使用字符串/选择器做参数时，一定要在页面销毁/退出时，主动销毁绑定的委托事件：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">beforeDestroy() {
    if (this.jsonClipboard) this.jsonClipboard.destroy();
},</pre>



<h2 class="wp-block-heading">四：总结</h2>



<p>总的来说，依托外部组件进行的事件绑定，一定要清楚它是如何绑定、如何解绑<br>在<code>Vue</code>中使用<code>Clipboard.js</code>，不管用何种方式进行初始化，它绑定的事件会一直存在</p>



<p>所以任何时候都应在组件销毁（前）进行手动销毁，即使指定<code>Dom</code>的事件绑定不会出现类似<code>bug</code>，但绑定的事件会一直存在于内存中，对性能也是一种负担</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ES6+新增与修改归纳（2019-2022）</title>
		<link>https://www.hu365.dev/blog/2022/07/98/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Sun, 31 Jul 2022 11:10:54 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[ES2019]]></category>
		<category><![CDATA[ES2020]]></category>
		<category><![CDATA[ES2021]]></category>
		<category><![CDATA[ES2022]]></category>
		<category><![CDATA[JAVASCRIPT]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=98</guid>

					<description><![CDATA[一：ES2019 1.1：Symbol.prototype.description Chrome Edge Firefox Safari Opera Opera Mobile 70+ 79+ 63+ 12.1+ 57+ 49+ 2018-10 2020-01  <a href="https://www.hu365.dev/blog/2022/07/98/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">一：ES2019</h2>



<h3 class="wp-block-heading">1.1：Symbol.prototype.description</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">70+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">12.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">57+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">49+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-11</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-12</mark></td></tr></tbody></table></figure>



<p>返回<code>Symbol</code>对象的可选描述的字符串</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Symbol('desc').description;        // "desc"
Symbol.iterator.description;       // "Symbol.iterator"
Symbol.for('foo').description;     // "foo"
`${Symbol('foo').description}bar`; // "foobar"</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/description">Symbol.prototype.description &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.2：Object.fromEntries</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">73+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">12.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-05</mark></td></tr></tbody></table></figure>



<p>把键值对列表转换为一个对象；这个键值对列表可以是<code>Array</code>、<code>Map</code>或者其它实现了可迭代协议（<code>Iteration protocols</code>）的可迭代对象<br>与<code>Object.entries</code>属于相反操作的方法</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">let entries = new Map([['foo', 'bar'], ['baz', 42]]);
let newObj = Object.fromEntries(entries);  // { foo: "bar", baz: 42 }
// 与Object.entries互转
let newEntries = Object.entries(newObj);   // [['foo', 'bar'], ['baz', 42]]
newObj = Object.fromEntries(newEntries );  // { foo: "bar", baz: 42 }</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries">Object.fromEntries() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.3：删除空格（trimStart/trimEnd/trimLeft/trimRight）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">66+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">61+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">12+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">53+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-07</mark></td></tr></tbody></table></figure>



<p><code>trimStart()</code>、<code>trimLeft()</code>：从一个字符串的开头移除空白字符<br><code>trimEnd()</code>、<code>trimRight()</code>：从一个字符串的末端移除空白字符<br><code>trimStart()</code>、<code>trimEnd()</code>为标准名称，<code>trimLeft()</code>、<code>trimRight()</code>为兼容web定义的别名</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const greeting = '   Hello world!   ';
greeting.trimStart();   // 'Hello world!   '
greeting.trimLeft();    // 'Hello world!   '
greeting.trimEnd();     // '   Hello world!'
greeting.trimRight();   // '   Hello world!'
greeting.trim();        // 'Hello world!' ES5的语法，移除两端空白字符</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart">String.prototype.trimStart() &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd">String.prototype.trimRight() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.4：Array.prototype.flat/flatMap</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">69+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">62+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">12+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">56+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">48+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-11</mark></td></tr></tbody></table></figure>



<p><code>flat([depth])</code>：按可指定的深度（<code>depth</code>）遍历数组，并将所有元素与子数组的元素合并为一个新数组；用于扁平化数组</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const arr1 = [0, 1, 2, [3, 4]];
arr1.flat();   // [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
arr2.flat();   // [0, 1, 2, [[3, 4]]]
arr2.flat(2);  // [0, 1, 2, [3, 4]]
arr2.flat(3);  // [0, 1, 2, 3, 4]
arr2.flat(4);  // [0, 1, 2, 3, 4]</pre>



<p><code>flatMap()</code>：使用映射函数映射每个元素（等同于<code>map</code>方法），然后将结果压缩成一个新数组（等同于<code>flat(1)</code>，<code>depth</code>始终为<code>1</code>）；可用于增删元素，实现<code>map</code>遍历下的<code>filter</code>功能，但是其工作效率较低，因为它会不断创建临时数组，并将数组数据复制到结果数据中</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const arr1 = [1, 2, 3, 4];
arr1.map(x => x * 2);                 // [2, 4, 6, 8]
arr1.flatMap(x => [x * 2]);           // [2, 4, 6, 8]
arr1.flatMap(x => [x * 2, x]);        // [2, 1, 4, 2, 6, 3, 8, 4]
arr1.flatMap(x => x > 2 ? [x] : []);  // [3, 4]</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">Array.prototype.flat() &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap">Array.prototype.flatMap() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h2 class="wp-block-heading">二：ES2020</h2>



<h3 class="wp-block-heading">2.1：String.prototype.matchAll</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">73+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">67+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-05</mark></td></tr></tbody></table></figure>



<p>返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器，该迭代器调用结果耗尽后，需要再次调用方法，获取一个新的迭代器<br>使用时正则表达式需使用<code>g</code>标志，否则抛出<code>TypeError</code><br>其内部做了一个<code>regexp</code>的复制，所以不像<code>exec</code>，<code>lastIndex</code>在字符串扫描时不会改变</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const regexp = RegExp('foo[a-z]*','g');
const str = 'table football, foosball';

// 结果耗尽，迭代器为空
const m1 = str.matchAll(regexp);
Array.from(m1);          // [Array(1), Array(1)]
Array.from(m1);          // []

// 与 exec() 的对比，不用反复取值，直接遍历
let match;
while ((match = regexp.exec(str)) !== null) {
    console.log(match); // ['football', ...] ['foosball', ...]
}
const m2 = str.matchAll(regexp);
for (match of m2) {
    console.log(match); // ['football', ...] ['foosball', ...]
}

// 与 match() 的对比，结果包含分组捕获
const regexp2 = /t(e)(st(\d?))/g;
const str2 = 'test1test2';
str2.match(regexp2); // ['test1', 'test2']
let array = [...str2.matchAll(regexp2)];
array[0];  // ['test1', 'e', 'st1', '1', index: 0, ...]
array[1];  // ['test2', 'e', 'st2', '2', index: 5, ...]</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll">String.prototype.matchAll() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.2：BigInt</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①67+/76+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①68+<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">/</mark>70+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①54+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①48+/54+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">19-05/19-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">19-07/19-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">18-11/19-10</mark></td></tr></tbody></table><figcaption class="wp-element-caption">①：toLocaleString 方法不支持参数：locales、options</figcaption></figure>



<p>内置对象，它提供了一种方法来表示大于<code>2^53 - 1</code>的整数，这原本是<code>Javascript</code>中可以用<code>Number</code>表示的最大数字（<code>Number.MAX_SAFE_INTEGER</code>），<code>BigInt</code>可以表示任意大的整数</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt">BigInt &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.3：Promise.allSettled</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">76+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">71+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">54+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-10</mark></td></tr></tbody></table></figure>



<p>返回一个在所有给定的<code>promise</code>都已经<code>fulfilled</code>或<code>rejected</code>后的<code>promise</code>，并带有一个对象数组，每个对象表示对应的<code>promise</code>结果<br>有多个彼此不依赖的异步任务成功完成时，或者您总是想知道每个<code>promise</code>的结果时，通常使用它<br><code>Promise.all()</code>更适合彼此相互依赖或者在其中任何一个<code>reject</code>时立即结束</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
    setTimeout(reject, 100, 'foo');
});
const promises = [promise1, promise2];

Promise.allSettled(promises)
    .then((results) => results.forEach(result => console.log(result)));
// { status: "fulfilled", value: 3 }
// { status: "rejected", reason: "foo" }

Promise.all(promises)
    .then((results) => console.log(results))
    .catch(console.error);
// foo</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled">Promise.allSettled() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.4：globalThis</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">71+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">65+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">12.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">58+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">50+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-02</mark></td></tr></tbody></table></figure>



<p>提供一个标准的方式来获取不同环境下的全局<code>this</code>对象，确保可以在有无窗口的各种环境下正常工作，不必担心它的运行环境<br>它既是<code>Web</code>中的<code>window</code>、<code>self</code>或者<code>frames</code>，<code>Web Workers</code>中的<code>self</code>，也是<code>Node.js</code>中的<code>global</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">globalThis === this &amp;&amp;
globalThis === self &amp;&amp;
globalThis === window;
// true</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/globalThis">globalThis &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.5：可选链操作符（?.）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">80+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">80+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">74+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">67+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">57+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td></tr></tbody></table></figure>



<p>允许读取位于连接对象链深处的属性的值，而不必明确验证链中的每个引用是否有效<br>引用为空（<code>null</code>或<code>undefined</code>）的情况下不会引起错误，短路返回值为<code>undefined</code><br>函数调用时，如果给定的函数不存在，也返回<code>undefined</code><br>此操作符仅用于取值，不能用于赋值</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const adventurer = {
  name: 'Alice',
  cat: { name: 'Dinah' }
};
const dogName = adventurer.dog?.name; // undefined
adventurer.someNonExistentMethod?.(); // undefined</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining">可选链操作符 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.6：空值合并操作符（??）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">80+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">80+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">72+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">67+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">57+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td></tr></tbody></table></figure>



<p>逻辑操作符，当左侧的操作数为空（<code>null</code>或<code>undefined</code>）时，返回其右侧操作数，否则返回左侧操作数<br>逻辑或（||）的判断条件是“假”（<code>falsy</code>），<code>??</code>的判断条件为“空”（<code>nullish</code>：<code>null</code>或<code>undefined</code>）</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">null ?? 'string';  // "string"
null || 'string';  // "string"
0 ?? 42;  // 0
0 || 42;  // 42</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">空值合并运算符 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h2 class="wp-block-heading">三：ES2021</h2>



<h3 class="wp-block-heading">3.1：String.prototype.replaceAll</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">77+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">71+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td></tr></tbody></table></figure>



<p><code>str.replaceAll(regexp|substr, newSubstr|function)</code><br>第一个参数可以是一个字符串或一个<code>RegExp</code>（需包含标志<code>g</code>，否则<code>TypeError</code>），用来匹配需替换的字符<br>第二个参数可以是一个字符串或一个在每次匹配时被调用的函数<br>效果就是赋予<code>String.prototype.replace</code>全局替换的功能，使用带<code>g</code>的<code>RegExp</code>时没有区别</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const p = '000222HHHXXX';
p.replaceAll('0', '5');    // '555222HHHXXX'
p.replace('0', '5');       // '500222HHHXXX'
const regex = /h/ig;
p.replaceAll(regex, 'O');  // '000222OOOXXX'
p.replace(regex, 'O');     // '000222OOOXXX'</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll">String.prototype.replaceAll() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.2：Promise.any</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">71+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td></tr></tbody></table></figure>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/any">Promise.any() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.3：WeakRef</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">84+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></td></tr></tbody></table></figure>



<p>允许保留对另一个对象的弱引用，且不会阻止被弱引用对象被垃圾回收机制回收<br>因为各版本的垃圾回收机制可能存在差异，难以保证实现效果能保证一样，所以正确使用<code>WeakRef</code>对象时需要仔细的考虑，最好尽量避免使用<br>没有特殊需求很难用到的一个东西，具体要用还得去看详细的文档说明</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakRef">WeakRef &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.4：逻辑赋值（&amp;&amp;=、||=、??=）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">85+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">71+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></mark></td></tr></tbody></table></figure>



<p><code>&amp;&amp;=</code>左侧变量为<code>truthy</code>时，进行赋值；<code>x &amp;&amp;= y</code>等价于<code>x &amp;&amp; (x = y)</code>，非等价<code>x = x &amp;&amp; y</code><br><code>||=</code>左侧变量为<code>falsy</code>时，进行赋值；<code>x ||= y</code>等价于<code>x || (x = y)</code>，非等价<code>x = x || y</code><br><code>??=</code>左侧变量为<code>nullish</code>时，进行赋值；<code>x ??= y</code>等价于<code>x ?? (x = y)</code>，非等价<code>x = x ?? y</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const a = { duration: 50, title: '', name: '' };

a.duration &amp;&amp;= 10;
console.log(a.duration);  // 10
a.duration ||= 20;
console.log(a.duration);  // 10
a.duration ??= 30;
console.log(a.duration);  // 10

a.title &amp;&amp;= 'S1';
console.log(a.title);     // ''
a.title ||= 'S2';
console.log(a.title);     // 'S2'
a.title ??= 'S3';
console.log(a.title);     // 'S2'

a.null1 &amp;&amp;= 'S1';
console.log(a.null1);     // undefined
a.null2 ??= 'S2';
console.log(a.null2);     // 'S2'
a.null3 ||= 'S3';
console.log(a.null3);     // 'S3'

a.name ??= 'S3';
console.log(a.name);      // ''
a.name ||= 'S2';
console.log(a.name);      // 'S2'</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment">Logical AND assignment (&amp;&amp;=) &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment">Logical OR assignment (||=) &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment">逻辑空赋值 (??=) &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.5：数字分隔符（_）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">75+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">70+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">13+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">62+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></mark></mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></mark></mark></td></tr></tbody></table></figure>



<p>使用下划线 (_, U+005F) 作为分隔符，为方便数字文字的可读性，包括整数和浮点数</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 可用于金额，方便阅读
123_00                  // 123元，12300分/$123，123美分

// 通用写法，千分位分割
12_000                  // 12k
1_234_500               // 1,234,500
1_000_000_000           // 10亿
101_475_938.38          // 亿级单位

// 小数
0.000_001               // 百万分之一
1e10_000                // 10^10_000，10^10000</pre>



<ul>
<li><a href="https://github.com/tc39/proposal-numeric-separator">proposal-numeric-separator</a></li>
</ul>



<h2 class="wp-block-heading">四：ES2022</h2>



<h3 class="wp-block-heading">4.1：Class：公有类字段（Public class fields）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">72+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">69+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">51+</mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-03</mark></td></tr></tbody></table></figure>



<p>公有字段都是可编辑、可枚举和可配置的属性，且参与原型的继承，即派生类可通过原型链访问字段<br>字段是在对应的构造函数运行之前添加的，所以在构造函数中可以直接访问字段<br>字段是通过<code>[[Define]]</code>语义（本质上是<code>Object.defineProperty()</code>）添加，其声明并不会触发<code>setter</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class ClassField {
    static baseField = 'base field';
    field = 'base';
    // setter
    set fieldSetted(val) {
        console.log('setter：' + val);
    }
    constructor() {
        this.field += ' plus';           // 构造函数中访问字段
        console.log('Base constructor:', this.field);
    }
}
class SubClass extends ClassField {
    field = 'sub';
    // fieldSetted = 'set_1';            // 字段声明不会触发 setter
    constructor() {
        super();
        this.field = this.baseField;     // 实例对象属性值为 undefined
        this.field = SubClass.baseField; // 静态属性原项链访问
        this.fieldSetted = 'set_2';      // this实例赋值，触发 setter
        console.log('Sub constructor:', this.field);
    }
}
new SubClass();
// Base constructor: base plus       super() 中 ClassField 构造
// setter：set_2                     this.fieldSetted 触发 setter
// Sub constructor: base field       通过原型链查找赋值为 'base field'</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Public_class_fields">公有类字段 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.2：Class：私有类字段/方法（Private class fields/methods）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②74+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②14.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②62+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②53+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2019-07</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">②84+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">②84+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">②70+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">②60+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-09</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">91+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">91+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">77+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">64+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-05</mark></td></tr></tbody></table><figcaption class="wp-element-caption">①：不支持私有方法；②：不支持 in 判断</figcaption></figure>



<p>通过增加哈希前缀<code>#</code>来定义私有类字段/方法，<code>#</code>是名称本身的一部分，声明和访问时也需要加上</p>



<ul>
<li>私有字段必须先声明，引用未声明的私有字段会抛出语法错误</li>



<li>私有字段仅限在定义它的类的内部访问，派生类/外部调用都会抛出错误</li>



<li>私有字段不能删除，调用<code>delete</code>会抛出语法错误</li>



<li>可使用<code>in</code>运算符检查私有字段是否存在，存在返回<code>true</code>，不存在返回<code>false</code></li>



<li>私有方法可以是异步、生成器、异步生成器方法，其限制同私有字段一样</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class ClassField {
    static #staticField;
    #privateField;

    // 方法中调用私有属性/方法，this只能是当前类，否则报TypeError
    static #baseStaticMethod() {
        this.#staticField = 42;
        return this.#staticField;
    }
    static baseStaticMethod1() {
        return ClassField.#baseStaticMethod.call(ClassField);
    }
    static baseStaticMethod2() {
        return ClassField.#baseStaticMethod.call(this);
    }

    constructor() {
        this.#privateField = 42;     // 直接调用，没问题
        delete this.#privateField;   // delete 操作，语法错误
        this.#undeclaredField = 444; // 未声明字段，语法错误
    }
}
const instance = new ClassField()
instance.#privateField === 42;   // 外部调用，语法错误

class SubClass extends ClassField {};
SubClass.baseStaticMethod1();      // this 指向 ClassField，正常调用
SubClass.baseStaticMethod2();      // this 指向 SubClass，TypeError</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Private_class_fields">类私有域 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.3：Class：静态初始化块（static initialization blocks）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">94+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">94+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">93+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></mark></mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">80+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">66+</mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-12</mark></td></tr></tbody></table></figure>



<p>使用<code>static{...}</code>的方式在类中添加静态初始化块，同一个类中可以存在多个初始化块，执行顺序即为书写顺序</p>



<ul>
<li>块内声明变量为局部变量，不会被提升，<code>var</code>定义变量、<code>function</code>函数也不会提升</li>



<li>块内可访问私有属性/字段，包括公有字段和私有字段</li>



<li>块内的<code>this</code>指的是类的构造函数对象，可用于在块内访问静态属性/字段/方法</li>



<li>块内的<code>super</code>可以访问超类的静态属性，包括其属性、字段、方法</li>



<li>块内代码是立即执行的</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var y = 'Outer y';
class ClassA {
    static field = 'Inner y';
    static #field = 'Inner y';
    static {
        var y = this.field;
    }
    static {
        console.log(this.field);   // 访问静态属性
        console.log(this.#field);  // 访问私有静态属性
    }
}
class ClassB extends ClassA {
    static {
        console.log(super.field);  // 访问父类静态属性
    }
}
console.log(y); // 块内 var 变量不提升</pre>



<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_static_initialization_blocks">Class static initialization blocks &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.4：取值：.at()（Array、String、TypedArray）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">92+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">92+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15.4+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">①②65+</mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2022-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-10</mark></td></tr></tbody></table><figcaption class="wp-element-caption">①：未实现 Array；②：未实现 String</figcaption></figure>



<p><code>Array</code>、<code>String</code>、<code>TypedArray</code>（二进制缓冲区），新增<code>at(index)</code>方法，获取指定索引的项目值<br><code>index</code>索引为负数时，表示从数组末端开始的相对索引，当索引值超出有效范围，返回结果为<code>undefined</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const colors = ['red', 'green', 'blue'];
const sentence = 'The quick brown fox jumps over the lazy dog.';
const int8 = new Int8Array([0, 10, -10, 20, -30, 40, -50]);

colors.at(colors.length - 2);      // 'green'
colors.at(-2);                     // 'green'
sentence.at(sentence.length - 2);  // 'g'
sentence.at(-2);                   // 'g'
int8.at(int8.length - 2);          // 40
int8.at(-2);                       // 40
</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/at">Array.prototype.at() &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/at">String.prototype.at() &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/at">TypedArray.prototype.at() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.5：Object.hasOwn()</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">93+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">93+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">92+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15.4+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">66+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2022-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-12</mark></td></tr></tbody></table></figure>



<p><code>hasOwn(instance, prop)</code>用来判断指定对象是否包含指定属性，仅限该对象声明的属性，继承属性不算<br>正常情况下，使用<code>hasOwnProperty</code>也可以得到效果结果，但<code>hasOwnProperty</code>属于继承属性，当原型链上的该方法不存在、或被修改之后，该方法可能会失效、或者抛出错误</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const obj = {};
obj.prop = 'exists';
obj.prop2 = null;
obj.prop3 = undefined;

Object.hasOwn(obj, 'prop');             // true
Object.hasOwn(obj, 'toString');         // false
Object.hasOwn(obj, 'hasOwnProperty');   // false
Object.hasOwn(obj, 'prop2');            // true
Object.hasOwn(obj, 'prop3');            // true
Object.hasOwn(obj, 'prop4');            // false

'prop' in obj;                          // true
'toString' in obj;                      // true
'hasOwnProperty' in obj;                // true
'prop2' in obj;                         // true
'prop3' in obj;                         // true
'prop4' in obj;                         // false

const foo = Object.create(null);
foo.prop = 'exists';
Object.hasOwn(foo, 'prop');             // true
'prop' in foo;                          // true
foo.hasOwnProperty('prop');             // TypeError</pre>



<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn">Object.hasOwn() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.6：Error.prototype.cause</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">93+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">93+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">91+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></mark></mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></mark></mark></mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></mark></mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></mark></mark></td></tr></tbody></table></figure>



<p>该属性用来描述引起该错误的特定原始原因，其值是在<code>options.cause</code>参数中传递给<code>Error()</code>构造函数的值<br>主要用来封装机器语言的报错，将原因修改为通俗语言表达，用于参考差错</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function makeRSA(p, q) {
    if (!Number.isInteger(p) || !Number.isInteger(q)) {
        throw new Error('生成 RSA 密钥需要输入整数.', {
            cause: { code: '非整数', value: [p, q] },
        });
    }
    if (!areCoprime(p, q)) {
        throw new Error('生成 RSA 密钥需要输入两个互质整数.', {
            cause: { code: '非质数', values: [p, q] },
        })
    }
    // …
}</pre>



<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause">Error.prototype.cause &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://github.com/tc39/proposal-error-cause">tc39/proposal-error-cause</a></li>
</ul>



<h3 class="wp-block-heading">4.7：正则修饰符：d</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">90+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">88+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">76+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">64+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-0</mark>5</td></tr></tbody></table></figure>



<p>使用该修饰符，会在结果中添加一个属性：<code>indices</code><br>该属性的值包含所有匹配项的索引信息，其索引值是相对的原始字符串的索引<br>未匹配数据时，将返回<code>undefined</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const re1 = /a+(?&lt;Z>z)?/d;
const s1 = "xaaaz";
const m1 = re1.exec(s1);
console.log(m1.indices);
/*[
    'aaaz', 
    'z', 
    index: 1, 
    input: 'xaaaz', 
    groups: {
        Z: "z"
    }, 
    indices: [
        [1, 5], 
        [4, 5], 
        groups: {
            Z: [4, 5]
        }
    ]
]*/
// 没有匹配时，返回 `undefined`:
const m2 = re1.exec("xaaay");
m2.indices[1] === undefined;
m2.indices.groups["Z"] === undefined;</pre>



<ul>
<li><a href="https://github.com/tc39/proposal-regexp-match-indices">tc39/proposal-regexp-match-indices</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ES6+新增与修改归纳（2015-2018）</title>
		<link>https://www.hu365.dev/blog/2022/06/63/</link>
		
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Wed, 15 Jun 2022 12:06:00 +0000</pubDate>
				<category><![CDATA[前端笔记]]></category>
		<category><![CDATA[ES2015]]></category>
		<category><![CDATA[ES2016]]></category>
		<category><![CDATA[ES2017]]></category>
		<category><![CDATA[ES2018]]></category>
		<category><![CDATA[JAVASCRIPT]]></category>
		<guid isPermaLink="false">https://www.hu365.dev/?p=63</guid>

					<description><![CDATA[文章按年份事件顺序进行统计，主要参考资料： 最新浏览器主版本，不含更新版本 Chrome/Edge/Opera 为 Blink 内核；Firefox 为 Gecko 内核；Safari/IOS 为 WebKit 内核本文目前主要讨论PC浏览器兼容 一：ES20 <a href="https://www.hu365.dev/blog/2022/06/63/" class="cosmoswp-btn">阅读更多</a>]]></description>
										<content:encoded><![CDATA[
<p>文章按年份事件顺序进行统计，主要参考资料：</p>



<ol>
<li><a href="http://kangax.github.io/compat-table/es6/">ECMAScript 6 compatibility table (kangax.github.io)</a></li>



<li><a href="https://developer.mozilla.org/en-US/">MDN Web Docs (mozilla.org)</a></li>
</ol>



<p>最新浏览器主版本，不含更新版本</p>



<ul>
<li>Chrome：104：2022-08-02</li>



<li>Edge：104：2022-08-05</li>



<li>Firefox：103：2022-07-26</li>



<li>Safari：15.6：2022-07-20</li>



<li>Opera：[Desktop] 89：2022-07-07；[Mobile] 69：2022-05-12</li>
</ul>



<p>Chrome/Edge/Opera 为 Blink 内核；Firefox 为 Gecko 内核；Safari/IOS 为 WebKit 内核<br>本文目前主要讨论PC浏览器兼容</p>



<h2 class="wp-block-heading" id="es-2015">一：ES2015</h2>



<p>鉴于ES6新增属性太多，这里只归纳几个</p>



<h3 class="wp-block-heading">1.1：尾调用优化（Tail Call Optimization/Proper Tail Calls）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center">❌</td><td class="has-text-align-center" data-align="center">❌</td><td class="has-text-align-center" data-align="center">❌</td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">10+</mark></td><td class="has-text-align-center" data-align="center">❌</td><td class="has-text-align-center" data-align="center">❌</td></tr><tr><td class="has-text-align-center" data-align="center">➖</td><td class="has-text-align-center" data-align="center">➖</td><td class="has-text-align-center" data-align="center">➖</td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-09</mark></td><td class="has-text-align-center" data-align="center">➖</td><td class="has-text-align-center" data-align="center">➖</td></tr></tbody></table></figure>



<p>这个伴随ES6就被谈及很多的一个优化；不过很可惜，到目前为止仍只有 Safari 一家实现了该优化，其他几家在加入该优化过程中遇到各种问题，甚至之后很长一段时间都不会有什么积极的更新了；相关故事可以读读：</p>



<ul>
<li><a href="https://stackoverflow.com/a/54721813/9728145">Tail Call Optimization implementation in Javascript Engines &#8211; Stack Overflow</a></li>



<li><a href="https://world.hey.com/mgmarlow/what-happened-to-proper-tail-calls-in-javascript-5494c256">What happened to proper tail calls in JavaScript?</a></li>
</ul>



<h3 class="wp-block-heading">1.2：二进制数/八进制数（Binary Integer Literal/Octal Integer Literal<strong>）</strong></h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">41+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">12+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">25+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">9+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">28+</mark></td><td class="has-text-align-center" data-align="center">✅</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-05</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-0</mark>7</td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2013-09</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-10</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-05</mark></td><td class="has-text-align-center" data-align="center"><strong><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">➖</mark></strong></td></tr></tbody></table></figure>



<p>二进制数：以 0b/0B开头，后面接数字0-1<br>八进制数：以 0o/0O开头，后面接数字0-7；ES5非严格模式支持前缀0的八进制表示法，ES6相当于规范这几种表示法，和十六进制表示法一样<br>十六进制：以 0x/0X 开头，后面接数字0-9/a-f/A-F</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="dracula" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 二进制
0b1 === 1 &amp;&amp; 0B1 === 1;
0b10 === 2 &amp;&amp; 0B10 === 2;
Number(0b1) === 1 &amp;&amp; Number(0B10) === 2;
// 八进制
0o1 === 1 &amp;&amp; 0O1 === 1;
0o10 === 8 &amp;&amp; 0O10 === 8;
Number(0o1) === 1 &amp;&amp; Number(0o10) === 8;
// 十六进制
0x1 === 1 &amp;&amp; 0X1 === 1;
0x10 === 16 &amp;&amp; 0X10 === 16;
Number(0x1) === 1 &amp;&amp; Number(0X10) === 16;</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#%E6%95%B0%E5%AD%97%E5%AD%97%E9%9D%A2%E9%87%8F">语法和数据类型 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.3：正则修饰符：y、u</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">49+/50+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">13+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">3+/46+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">10+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">36+/37+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">36+/37+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">16-03/16-04</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-11</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">08-06/16-04</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">16-03/16-05</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">16-03/16-06</mark></mark></td></tr></tbody></table></figure>



<p><code>y</code>：<code>sticky</code> 粘性标志，下一次匹配一定在&nbsp;<code>lastIndex</code>&nbsp;位置开始；<code>RegExp.prototype.sticky</code> 只读属性判断是否启用 <code>y</code> 标志<br><code>u</code>：<code>unicode</code> 相关特性；<code>RegExp.prototype.unicode<code> </code></code>只读属性判断是否启用 <code>u</code> 标志</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const text = '123 456';
const regY = /\d/y;
const regG = /\d/g;
let result;
// 打印3次，在匹配完‘3’之后，lastIndex 为3，\s（空格）未匹配成功，直接结束
while (result = regY.exec("123 456")) {
    console.log(result, regY.lastIndex);
}
// 打印6次，lastIndex 为 3 时未匹配成功，则 lastIndex + 1 继续匹配，直到全部匹配完
while (result = regG.exec("123 456")) {
    console.log(result, regG.lastIndex);
}</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp#%E4%BD%BF%E7%94%A8%E5%B8%A6%E6%9C%89_sticky_%E6%A0%87%E5%BF%97%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F">RegExp(正则表达式) &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.4：Reflect</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">49+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">12+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">42+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">10+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">36+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">36+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-03</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-07</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-11</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-03</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2016-03</mark></td></tr></tbody></table></figure>



<p><code>Reflect</code>&nbsp;对象是一个内置对象，提供拦截<code>JavaScript</code>操作的方法；其所有属性和方法都是静态的</p>



<p>静态方法参数都有类型要求，类型不匹配会报类型错误<code>TypeError</code>；与之相类似的<code>Object</code>方法则会进行强制转换，部分方法在<code>ES5</code>会报错，在<code>ES6</code>被修改为强制转换：<code>Object.keys</code>、<code>Object.getOwnPropertyNames</code>、<code>Object.assign</code>等</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Reflect.apply(); // Function.prototype.apply() 
Reflect.construct(); // new 构造函数
Reflect.has(); // name in Object
Reflect.getPrototypeOf(); // Object.getPrototypeOf()
                          // ES6之前不会进行强制转换，之后会
Reflect.isExtensible(); // Object.isExtensible()

// @return {Boolean} 操作是否成功
Reflect.defineProperty(); // Object.defineProperty() 返回对象
Reflect.deleteProperty(); // delete Objet[name] 返回 true
                          // 除非 configurable=false（非严格模式）
Reflect.get(); // Objet[name]
Reflect.set(); // Objet[name] = value
Reflect.preventExtensions(); // Object.preventExtensions() 返回对象
Reflect.setPrototypeOf(); // Object.setPrototypeOf() 返回对象

// @return {Object|undefined} 属性描述符
Reflect.getOwnPropertyDescriptor(); // Objet.getOwnPropertyDescriptor()

// @return {(Symbol|String)[]} 属性名列表，包含不可枚举属性、Symbol属性
Reflect.ownKeys(); // Object.keys 不含不可枚举、Symbol
                   // Object.getOwnPropertyNames 含不可枚举
                   // Object.getOwnPropertySymbols 含不可枚举</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect">Reflect &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.5：内置Symbol（Well-known Symbols）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">73+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">79+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">78+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">14+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">60+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">52+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2019-03</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2020-09</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2019-04</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2019-05</mark></td></tr></tbody></table><figcaption class="wp-element-caption">因为每个属性值被添加到浏览器的时间不同，此处浏览器版本为最近一次添加属性的版本</figcaption></figure>



<p>内置Symbol，通常被用作对象或类的属性键，对应的值用作规范算法的扩展、或者重构内部语言行为；该重构行为改仅针对修改的对象或类生效，不会修改全局的默认方法</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 迭代器：Symbol.iterator
const arr = [1,2,3];
arr[Symbol.iterator] = function* (...params) {
    for (let i=0;i&lt;arr.length;i++) {
        yield 2*arr[i];
    }
}
console.log(arr); // Array [1, 2, 3]
console.log([...arr]); // Array [2, 4, 6]

// 字符串替换、拆分：Symbol.replace、Symbol.split
const obj = {
    [Symbol.replace]: (origin, replaceTo)=> {
        return `__${origin}_${replaceTo}__`;
    },
    [Symbol.split]: (origin, limit)=> {
        return `${Array(2).fill(origin)}`;
    },
}
const str = 'test';
console.log(str.replace(obj, 'to')); // "__test_to__"
console.log(str.split(obj, 5)); // "test,test"</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol#%E4%BC%97%E6%89%80%E5%91%A8%E7%9F%A5%E7%9A%84_symbols">Symbol &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://262.ecma-international.org/6.0/#sec-well-known-symbols">ECMAScript 2015 Language Specification – ECMA-262 6th Edition (ecma-international.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.6：Array.prototype.splice</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">1+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">12+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">1+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">1+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">4+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">10.1+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2008-12</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-07</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2004-11</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2003-06</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2000-06</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2010-11</mark></td></tr></tbody></table></figure>



<p>这确实是ES6新标准，但是各大浏览器其实早就加入了该实现方法，新标准只是给他一个名分而已</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">Array.prototype.splice() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">1.7：Number.EPSILON</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">34+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">12+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">25+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">9+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">21+</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #008000;">21+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2014-04</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-07</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2013-10</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2015-09</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2014-05</mark></td><td class="has-text-align-center" data-align="center"><mark class="has-inline-color" style="background-color: rgba(0, 0, 0, 0); color: #443d66;">2014-04</mark></td></tr></tbody></table></figure>



<p>表示 1 与 Number 类型可表示的大于 1 的最小的浮点数之间的差值，可理解为：最小浮点数</p>



<p><br>可以用来判断浮点数之间的计算值比较，差值 <code>&lt; Number.EPSILON</code> 即认定为相等：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const x = 0.1, y = 0.2, z = 0.3;
const isEqual = (Math.abs(x + y - z) &lt; Number.EPSILON);</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON">Number.EPSILON &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h2 class="wp-block-heading">二：ES2016</h2>



<h3 class="wp-block-heading">2.1：幂运算（**/**=）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">39+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">41+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td></tr></tbody></table></figure>



<p>求幂，等效于<code>Math.pow</code>，也接受<code>BigInts</code>作为参数</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Exponentiation_assignment#browser_compatibility">Exponentiation assignment (**=) &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">2.2：Array.prototype.includes</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">43+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">9+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">34+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">34+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2015-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2015-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2015-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2015-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2015-12</mark></td></tr></tbody></table></figure>



<p><code>arr.includes(valueToFind[, fromIndex])</code>接受两个参数；</p>



<p>第一个参数不传，则默认为<code>undefined</code><br>第二个参数为查找开始的索引值，为可选参数：</p>



<ul>
<li><code>fromIndex &gt;= 0 &amp;&amp; fromIndex &lt;= arr.length - 1</code>：正常查找</li>



<li><code>fromIndex &gt; arr.length - 1</code>：返回<code>false</code></li>



<li><code>fromIndex &lt; 0</code>：计算<code>fromIndex = Math.max(0, fromIndex + arr.length)</code>之后再判断</li>
</ul>



<p><code>includes()</code>&nbsp;有意设计为通用方法，可以被用于其他类型（如类数组对象）的对象，包括<code>querySelectorAll</code>、<code>Object.keys</code>、<code>map.keys</code>等</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[].includes(); // false
[undefined].includes(); // true
[1,].includes(); // false
[1,,].includes(); // true
Array(2).includes(); // true

// 其他类型
[].includes.call(1, 1); // 数字，false
[].includes.call(true, true); // 布尔，false
[].includes.call(Symbol(1), 1); // Symbol，false
[].includes.call(BigInt(1), 1); // BigInt，false
[].includes.call(()=>{}, 1); // Function，false
[].includes.call(/\d/, 1); // RegExp，false
[].includes.call(null, null); // null，TypeError
[].includes.call(undefined, undefined); // undefined，TypeError
</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">Array.prototype.includes() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h2 class="wp-block-heading">三：ES2017</h2>



<h3 class="wp-block-heading">3.1：对象取值（values/entries）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">54+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">41+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">41+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td></tr></tbody></table></figure>



<p><code>Object.<code>values</code></code>对象自身的所有可枚举属性值的数组；顺序与使用<code>for...in</code>循环的顺序相同<br><code>Object.entries</code>对象自身可枚举属性的键值对数组；顺序与使用<code>for...in</code>循环的顺序相同</p>



<p><code>Object.keys</code>方法在浏览器中很早就实现了，直到<code>ES2015</code>成为标准；然后时隔两年，<code>Object.values</code>才成为新标准，浏览器也是跟随标准才实现该方法；所以对于一些较老的浏览器来说，很可能实现了<code>Object.keys</code>而没有实现<code>Object.values</code>/<code>Object.entries</code></p>



<p><code>Object.entries</code>最常用的作用估计就是转换成map了</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const obj = { foo: "bar", baz: 42 };
const map = new Map(Object.entries(obj));
console.log(map) // Map(2) {'foo' => 'bar', 'baz' => 42}</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/values">Object.values() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/entries">Object.entries() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.2：属性描述符（getOwnPropertyDescriptors）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">54+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">41+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">41+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-10</mark></td></tr></tbody></table></figure>



<p>对象自身所有属性的描述符，没有任何自身属性，则返回空对象<br>主要用途：</p>



<ol>
<li>浅拷贝</li>
</ol>



<p>实现拷贝对象时，也拷贝它的原型、属性特性</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Object.create(
    Object.getPrototypeOf(obj),
    Object.getOwnPropertyDescriptors(obj)
);</pre>



<ol start="2">
<li>创建子类</li>
</ol>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 传统写法的另一种实现
function superclass() {}
superclass.prototype = {
    // 在这里定义方法和属性
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
    // 在这里定义方法和属性
}));</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors">Object.getOwnPropertyDescriptors() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.3：字符串填充（padStart/padEnd）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">57+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">48+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">44+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">43+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-09</mark></td></tr></tbody></table></figure>



<ul>
<li><code>str.padStart(targetLength [, padString])</code></li>
</ul>



<ul start="2">
<li><code>str.padEnd(targetLength [, padString])</code></li>
</ul>



<p><code>targetLength</code>为目标长度，只有大于字符本身长度时，才会执行填充，小于时是直接返回原字符<br><code>padString</code>为填充字符串，长度够时反复填充，长度不够时优先保留左侧字符</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/padStart">String.prototype.padStart() &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd">String.prototype.padEnd() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.4：函数尾逗号（trailing/final commas）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">58+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">14+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">45+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">43+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-09</mark></td></tr></tbody></table></figure>



<p>针对函数参数中的尾逗号，在函数定义、函数调用中，最后一个参数后面可追加逗号：<code>,</code><br>在没有参数、结构参数时，不能添加尾逗号：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 合法的写法
function f(p,) {}
(p,) => {};
f(p,);
Math.max(10, 20,);

// 不合法的写法
function f(,) {} // SyntaxError: missing formal parameter
f(,);            // SyntaxError: expected expression, got ','
(...p,) => {}    // SyntaxError: expected closing parenthesis, got ','</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Trailing_commas#%E5%87%BD%E6%95%B0%E4%B8%AD%E7%9A%84%E5%B0%BE%E5%90%8E%E9%80%97%E5%8F%B7">尾后逗号 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.5：异步函数（async/await）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">55+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">52+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">42+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">42+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-01</mark></td></tr></tbody></table></figure>



<p><code>async</code>和<code>await</code>关键字让我们可以用一种更简洁的方式写出基于<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise"><code>Promise</code></a>的异步行为，而无需刻意地链式调用<code>promise</code></p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function">async 函数 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">3.6：共享内存（SharedArrayBuffer/Atomics）</h3>



<p><code>SharedArrayBuffer</code></p>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">68+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">10+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">55+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2016-09</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td></tr></tbody></table><figcaption class="wp-element-caption">为应对幽灵漏洞，所有主流浏览器均默认于 2018 年 1 月 5 日禁用 SharedArrayBuffer；<br>在 2020 年，一种新的、安全的方法已经标准化，以重新启用 SharedArrayBuffer</figcaption></figure>



<p><code>Atomics</code></p>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center">①<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">87+</mark></td><td class="has-text-align-center" data-align="center">①<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">87+</mark></td><td class="has-text-align-center" data-align="center">②<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center">①②<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">15.2+</mark></td><td class="has-text-align-center" data-align="center">①<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">75+</mark></td><td class="has-text-align-center" data-align="center">①<mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-11</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-11</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-03</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2021-04</mark></td></tr></tbody></table><figcaption class="wp-element-caption">①：仅支持<code>SharedArrayBuffer</code>对象操作；②：不支持<code>waitAsync</code>方法</figcaption></figure>



<p><code>SharedArrayBuffer</code>对象用来表示一个通用的、固定长度的原始二进制数据缓冲区，类似于<code>ArrayBuffer</code>对象，它们都可以用来在共享内存（shared memory）上创建视图<br><code>Atomics</code>对象提供了一组静态方法对<code>SharedArrayBuffer</code>和<code>ArrayBuffer</code>对象进行原子操作</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer">SharedArrayBuffer &#8211; JavaScript | MDN (mozilla.org)</a></li>



<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Atomics">Atomics &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h2 class="wp-block-heading">四：ES2018</h2>



<h3 class="wp-block-heading">4.1：对象的剩余/展开属性（Object Rest/Spread Properties）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">60+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">55+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">11.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">44+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-07</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-08</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-12</mark></td></tr></tbody></table></figure>



<p>属性拓展符在对象中的拓展；在某些浏览器版本中即使支持拓展符<code>...</code>，但不一定支持在对象中使用</p>



<p>可用来实现对象的浅拷贝和合并，与<code><code>Object.assign()</code></code>作用类似，但<code>Object.assign()</code>函数会触发 <code>setters</code>，而展开语法则不会</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 剩余属性
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
// 展开属性
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax#%E6%9E%84%E9%80%A0%E5%AD%97%E9%9D%A2%E9%87%8F%E5%AF%B9%E8%B1%A1%E6%97%B6%E4%BD%BF%E7%94%A8%E5%B1%95%E5%BC%80%E8%AF%AD%E6%B3%95">展开语法 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.2：Promise.prototype.finally</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">63+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">18+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">58+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">11.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">50+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">45+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-12</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-05</mark></td></tr></tbody></table></figure>



<p>在<code>promise</code>结束时，无论结果是<code>fulfilled</code>或者是<code>rejected</code>，都会执行指定的回调函数</p>



<p>此方法是新增的方法，和<code>Promise.prototype.then</code>、<code>Promise.prototype.catch</code>拥有不同的兼容性表现，某些浏览器版本中存在兼容性问题</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally">Promise.prototype.finally() &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.3：正则修饰符：s</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">62+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">11.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">49+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">46+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-11</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-05</mark></td></tr></tbody></table></figure>



<p>启用<code>dotAll</code>模式，特殊字符<code>.</code>可匹配行终结符（换行符），相当于匹配“任意单个字符”：</p>



<ul>
<li>U+000A 换行符（<code>\n</code>）</li>



<li>U+000D 回车符（<code>\r</code>）</li>



<li>U+2028 行分隔符（line separator）</li>



<li>U+2029 段分隔符（paragraph separator）</li>
</ul>



<p><code>RegExp.prototype.dotAll</code>只读属性用来判断是否启用了<code>s</code>标志</p>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll">RegExp.prototype.dotAll &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.4：命名分组捕获（Named capture groups）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">64+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">11.1+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">51+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-07</mark></td></tr></tbody></table></figure>



<p>以前的分组捕获都是用索引去取值，用<code>result[0]</code>、<code>result[2]</code>的形式取值，很多场景都分不清它们是什么含义，于是就有了命名捕获分组；这真是贴心的更新，不过需要考虑老浏览器兼容性</p>



<ul>
<li><strong>命名（<code>(?&lt;name&gt;...)</code>）与取值（属性<code>groups</code>）</strong></li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 获取年月日的匹配
let re = /(?&lt;year>\d{4})-(?&lt;month>\d{2})-(?&lt;day>\d{2})/u;
let result = re.exec('2015-01-02');
// 以前的取值
let date = result[0];   // '2015-01-02'
let year = result[1];   // '2015'
let month = result[2];  // '01'
let day = result[3];    // '02'
// 命名取值
let date = result[0];             // '2015-01-02'
let year = result.groups.year;    // '2015'
let month = result.groups.month;  // '01'
let day = result.groups.day;      // '02'
// 也可以直接结构取值
let {groups: {year, month, day}} = re.exec('2015-01-02');</pre>



<ul start="2">
<li><strong>命名引用（<code>\k&lt;name&gt;</code>）</strong></li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// (?&lt;half>.*)：匹配任意字符，命名为half
// \k&lt;half>：引用命名为half的匹配，即与前面是相同匹配
// 匹配结果就是 ABA 的字符串模式
let duplicate = /^(?&lt;half>.*).\k&lt;half>$/;
duplicate.test('a*b');    // false
duplicate.test('a_a');    // true
duplicate.test('ab-ab');  // true
duplicate.test('aaaa');   // false
duplicate.test('aaaaa');  // true</pre>



<ul start="3">
<li><strong><code>String.prototype.replace</code>中的使用</strong></li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 把日期格式 yyyy-mm-dd 替换为 dd/mm/yyy
let str = '2015-02-01';
let re = /(?&lt;year>\d{4})-(?&lt;month>\d{2})-(?&lt;day>\d{2})/;
// 以往的写法
let result = str.replace(re, '$3/$2/$1'); // '01/02/2015'
// 命名分组写法
let result = str.replace(re, '$&lt;day>/$&lt;month>/$&lt;year>'); // '01/02/2015'</pre>



<ul>
<li><a href="https://github.com/tc39/proposal-regexp-named-groups">tc39/proposal-regexp-named-groups: Named capture groups for JavaScript RegExps (github.com)</a></li>
</ul>



<h3 class="wp-block-heading">4.5：后行断言（<strong>Lookbehind assertion</strong>）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">62+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">❌</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">49+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">46+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-10</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">➖</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-11</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-05</mark></td></tr></tbody></table></figure>



<p><code>(?&lt;=y)x</code>仅当&#8217;x&#8217;前面是&#8217;y&#8217;时，匹配&#8217;x&#8217;，这种叫做后行断言<br><code>(?&lt;!<em>y</em>)<em>x</em></code>仅当&#8217;x&#8217;前面不是&#8217;y&#8217;时，匹配&#8217;x&#8217;，这被称为反向否定查找</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">let str1 = 'JackSprat';
let str2 = 'TomSprat';
let re1 = /(?&lt;=Jack)Sprat/;  // 匹配 JackSprat 中的 Sprat
let re2 = /(?&lt;!=Jack)Sprat/; // 匹配 不是 JackSprat 中的 Sprat
re1.exec(str1); // ['Sprat', index: 4, input: 'JackSprat', groups: undefined]
re1.exec(str2); // null
re2.exec(str1); // ['Sprat', index: 4, input: 'JackSprat', groups: undefined]
re2.exec(str2); // ['Sprat', index: 3, input: 'TomSprat', groups: undefined]</pre>



<ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions#special-lookahead">正则表达式 &#8211; JavaScript | MDN (mozilla.org)</a></li>
</ul>



<h3 class="wp-block-heading">4.6：Unicode转义捕获（Unicode Property Escapes）</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">64+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">78+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">11.1</mark>+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">51+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-06</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-0</mark></mark>4</td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-02</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-0</mark>7</td></tr></tbody></table></figure>



<p>根据<code>Unicode</code>属性，用来匹配表情、标点符号、字母、甚至特定语言或文字等。同一符号可以拥有多种<code>Unicode</code>属性，属性则有<code>binary</code>(&#8220;<code>boolean-like</code>&#8220;)和<code>non-binary</code>之分<br>使用时必须依靠<code>\u</code>标识，使用转义字符<code>\p{...}</code> 和 <code>\P{...}</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Non-binary 属性
\p{Unicode 属性值}
\p{Unicode 属性名=Unicode 属性值}
// Binary and non-binary 属性
\p{UnicodeBinary 属性名}
// \P 为 \p 取反
\P{Unicode 属性值}
\P{UnicodeBinary 属性名}

let sentence = 'A ticket to 大阪 costs ¥2000 👌.';
let regexpEmojiPresentation = /\p{Emoji_Presentation}/gu;
sentence.match(regexpEmojiPresentation);  // ["👌"]

let regexpNonLatin = /\P{Script_Extensions=Latin}+/gu;
sentence.match(regexpNonLatin);  // [" ", " ", " 大阪 ", " ¥2000 👌."]

let regexpCurrencyOrPunctuation = /\p{Sc}|\p{P}/gu;
sentence.match(regexpCurrencyOrPunctuation);  // ["¥", "."]
</pre>



<ul>
<li><a href="https://github.com/tc39/proposal-regexp-unicode-property-escapes">tc39/proposal-regexp-unicode-property-escapes. (github.com)</a></li>
</ul>



<h3 class="wp-block-heading">4.7：Function.prototype.toString</h3>



<figure class="wp-block-table is-style-regular has-medium-font-size"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Chrome</td><td class="has-text-align-center" data-align="center">Edge</td><td class="has-text-align-center" data-align="center">Firefox</td><td class="has-text-align-center" data-align="center">Safari</td><td class="has-text-align-center" data-align="center">Opera</td><td class="has-text-align-center" data-align="center">Opera Mobile</td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">66+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">79+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">54+</mark></td><td class="has-text-align-center" data-align="center">❌</td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">53+</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #008000;" class="has-inline-color">47+</mark></td></tr><tr><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-04</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2020-01</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2017-06</mark></td><td class="has-text-align-center" data-align="center">➖</td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-05</mark></td><td class="has-text-align-center" data-align="center"><mark style="background-color: rgba(0, 0, 0, 0); color: #443d66;" class="has-inline-color">2018-07</mark></td></tr></tbody></table></figure>



<p>新规范：要求<code>Function.prototype.toString</code>的返回值与声明的源代码完全现统，包括空格和注释；或者因某种原因，主机没有源代码，则要求返回一个原生函数字符串</p>



<ul>
<li><a href="https://tc39.es/Function-prototype-toString-revision/#proposal-sec-function.prototype.tostring">Function.prototype.toString revision (tc39.es)</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
