杨玉前 發表於 2019-8-14 20:01:00

javaScript ES7 ES8 ES9 ES10 ES12新特性

<p>参考文献:&nbsp;https://tuobaye.com/2018/11/27/%E7%BB%86%E8%A7%A3JavaScript-ES7-ES8-ES9-%E6%96%B0%E7%89%B9%E6%80%A7/</p>
<p>http://www.imooc.com/article/291875</p>
<p>https://hijiangtao.github.io/2019/07/05/Diff-ECMAScript-2019/</p>
<p><span style="font-size: 18px"><strong>ES7</strong></span></p>
<p><strong>1.&nbsp;Array.prototype.includes()方法</strong></p>
<div class="cnblogs_code">
<pre>['a', 'b', 'c', 'd'].includes('b')         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
['a', 'b', 'c', 'd'].includes('b', 1)      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
['a', 'b', 'c', 'd'].includes('b', 2)      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> ary1 =<span style="color: rgba(0, 0, 0, 1)"> ;
console.log(ary1.indexOf(NaN))</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">-1</span>
console.log(ary1.includes(NaN))<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">true</span></pre>
</div>
<p><strong>2.&nbsp;求幂运算符(**)</strong></p>
<p>用<code>**</code>来替代Math.pow。</p>
<div class="cnblogs_code">
<pre>4 ** 3</pre>
</div>
<p>等价于</p>
<div class="cnblogs_code">
<pre>Math.pow(4,3)</pre>
</div>
<div class="cnblogs_code">
<pre>let n = 4<span style="color: rgba(0, 0, 0, 1)">;
n </span>**= 3;</pre>
</div>
<p><span style="font-size: 18px"><strong>ES8</strong></span></p>
<p>1.&nbsp;Async Functions</p>
<p>Async Functions也就是我们常说的Async/Await。Async/Await是一种用于处理<strong>JS异步操作</strong>的语法糖,可以帮助我们摆脱回调地狱,编写更加优雅的代码。</p>
<p>通俗的理解,async关键字的作用是告诉编译器对于标定的函数要区别对待。当编译器<strong>遇到标定的函数中的await关键字时,要暂时停止运行,带到await标定的函数处理完毕后,再进行相应操作</strong>。如果该函数fulfilled了,则返回值是resolve value,否则得到的就是reject value。</p>
<p>拿普通的promise写法来对比:</p>
<div class="cnblogs_code">
<pre>async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    const result </span>=<span style="color: rgba(0, 0, 0, 1)"> await otherAsyncFunc();
    console.log(result);
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Equivalent to:</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> otherAsyncFunc()
    .then(result </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log(result);
    });
}</span></pre>
</div>
<p>并行处理多个函数:</p>
<div class="cnblogs_code">
<pre>async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    const </span>=<span style="color: rgba(0, 0, 0, 1)"> await Promise.all([
      otherAsyncFunc1(),
      otherAsyncFunc2(),
    ]);
    console.log(result1, result2);
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Equivalent to:</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Promise.all([
      otherAsyncFunc1(),
      otherAsyncFunc2(),
    ])
    .then( </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log(result1, result2);
    });
}</span></pre>
</div>
<p>处理错误:</p>
<div class="cnblogs_code">
<pre>async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
      await otherAsyncFunc();
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
      console.error(err);
    }
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Equivalent to:</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> asyncFunc() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> otherAsyncFunc()
    .</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.error(err);
    });
}</span></pre>
</div>
<p><strong>2.&nbsp;SharedArrayBuffer和Atomics</strong></p>
<p>SharedArrayBuffer允许在多个 workers 和主线程之间共享 SharedArrayBuffer 对象的字节。这种共享有两个好处:</p>
<ul>
<li>可以更快地在 workers 之间共享数据。</li>
<li>workers 之间的协调变得更简单和更快(与 postMessage() 相比)</li>
</ul>
<p>API:</p>
<p>  构造函数: new SharedArrayBuffer(length)</p>
<p>  静态属性:&nbsp;SharedArrayBuffer</p>
<p>  实例属性:&nbsp;SharedArrayBuffer.prototype.byteLength()</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SharedArrayBuffer.prototype.slice(start, end)</p>
<p>Atomics 方法可以用来与其他 workers 进行同步。以下两个操作可以让你读取和写入数据,并且不会被编译器重新排列:</p>
<ul>
<li>Atomics.load(ta : TypedArray, index)</li>
<li>Atomics.store(ta : TypedArray, index, value : T)</li>
</ul>
<p>这个想法是使用常规操作读取和写入大多数数据,而 Atomics 操作(load ,store 和其他操作)可确保读取和写入安全。通常,<strong>要使用自定义同步机制(例如)可以基于Atomics实现</strong>。</p>
<p>API:&nbsp;</p>
<p>Atomic 函数的主要操作数必须是 Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array 或 Uint32Array 的一个实例。它必须包裹一个 SharedArrayBuffer.</p>
<ul>
<ul>
<li>Atomics.load(ta : TypedArray, index) : T<br>读取和返回 ta 上的元素,返回数组指定位置上的值。</li>
<li>Atomics.store(ta : TypedArray, index, value : T) : T<br>在 ta 上写入 value,并且返回 value。</li>
<li>Atomics.exchange(ta : TypedArray, index, value : T) : T<br>将 ta 上的元素设置为 value ,并且返回索引 index 原先的值。</li>
<li>Atomics.compareExchange(ta : TypedArray, index, expectedValue, replacementValue) : T<br>如果 ta 上的当前元素为 expectedValue , 那么使用 replacementValue 替换。并且返回索引 index 原先(或者未改变)的值。</li>





</ul>




</ul>
<ul>
<ul>
<li>Atomics.add(ta : TypedArray, index, value) : T<br>执行 ta += value 并返回 ta 的原始值。</li>
<li>Atomics.sub(ta : TypedArray, index, value) : T<br>执行 ta -= value 并返回 ta 的原始值。</li>
<li>Atomics.and(ta : TypedArray, index, value) : T<br>执行 ta &amp;= value 并返回 ta 的原始值。</li>
<li>Atomics.or(ta : TypedArray, index, value) : T<br>执行 ta |= value 并返回 ta 的原始值。</li>
<li>Atomics.xor(ta : TypedArray, index, value) : T<br>执行 ta ^= value 并返回 ta 的原始值。</li>





</ul>




</ul>
<ul>
<ul>
<li>Atomics.wait(ta: Int32Array, index, value, timeout=Number.POSITIVE_INFINITY) : (‘not-equal’ | ‘ok’ | ‘timed-out’)<br>如果 ta 的当前值不是 value ,则返回 ‘not-equal’。否则(等于value时)继续等待,直到我们通过 Atomics.wake() 唤醒或直到等待超时。 在前一种情况下,返回 ‘ok’。在后一种情况下,返回’timed-out’。timeout 以毫秒为单位。记住此函数执行的操作:“如果 ta 为 value,那么继续等待” 。</li>
<li>Atomics.wake(ta : Int32Array, index, count)<br>唤醒等待在 ta 上的 count workers。</li>





</ul>




</ul>
<p><strong>3.&nbsp;Object.values and Object.entries</strong></p>
<div class="cnblogs_code">
<pre>const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz'<span style="color: rgba(0, 0, 0, 1)"> };
Object.values(obj); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ['yyy', 'zzz', 'xxx']</span>
<span style="color: rgba(0, 0, 0, 1)">
Object.values(</span>'es8'); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ['e', 's', '8']</span></pre>
</div>
<div class="cnblogs_code">
<pre>const obj = ['e', 's', '8'<span style="color: rgba(0, 0, 0, 1)">];
Object.entries(obj); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [['0', 'e'], ['1', 's'], ['2', '8']]</span>
<span style="color: rgba(0, 0, 0, 1)">
const obj </span>= { 10: 'xxx', 1: 'yyy', 3: 'zzz'<span style="color: rgba(0, 0, 0, 1)"> };
Object.entries(obj); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]</span>
<span style="color: rgba(0, 0, 0, 1)">
Object.entries(</span>'es8'); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [['0', 'e'], ['1', 's'], ['2', '8']]</span></pre>
</div>
<p><strong>4.&nbsp;String padding</strong></p>
<p>为 String 对象增加了 2 个函数:padStart 和 padEnd。填补字符串的首部和尾部,为了使得到的结果字符串的长度能达到给定的长度(targetLength)。你可以通过特定的字符,或者字符串,或者默认的空格填充它。</p>
<pre><span class="line">str.padStart(targetLength [, padString])</span></pre>
<pre><em><span class="line"><span class="line">str.padEnd(targetLength [, padString])<br><br></span></span></em></pre>
<div class="cnblogs_code">
<pre>'es8'.padStart(2);          <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8'</span>
'es8'.padStart(5);          <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8'</span>
'es8'.padStart(6, 'woof');<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'wooes8'</span>
'es8'.padStart(14, 'wow');<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'wowwowwowwoes8'</span>
'es8'.padStart(7, '0');   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> '0000es8'</span>

'es8'.padEnd(2);            <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8'</span>
'es8'.padEnd(5);            <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8'</span>
'es8'.padEnd(6, 'woof');    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8woo'</span>
'es8'.padEnd(14, 'wow');    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es8wowwowwowwo'</span>
'es8'.padEnd(7, '6');       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'es86666'</span></pre>
</div>
<p><strong>5.&nbsp;Object.getOwnPropertyDescriptors</strong></p>
<div class="cnblogs_code">
<pre>const obj =<span style="color: rgba(0, 0, 0, 1)"> {
get es7() { </span><span style="color: rgba(0, 0, 255, 1)">return</span> 777<span style="color: rgba(0, 0, 0, 1)">; },
get es8() { </span><span style="color: rgba(0, 0, 255, 1)">return</span> 888<span style="color: rgba(0, 0, 0, 1)">; }
};
Object.getOwnPropertyDescriptor(obj);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   es7: {</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   configurable: true,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   enumerable: true,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   get: function es7(){}, //the getter function</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   set: undefined</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   },</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   es8: {</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   configurable: true,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   enumerable: true,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   get: function es8(){}, //the getter function</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   set: undefined</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   }</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> }</span></pre>
</div>
<p><strong>6.&nbsp;结尾逗号</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 参数定义时</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> foo(
    param1,
    param2,
) {}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 函数调用时</span>
<span style="color: rgba(0, 0, 0, 1)">foo(
    </span>'abc'<span style="color: rgba(0, 0, 0, 1)">,
    </span>'def'<span style="color: rgba(0, 0, 0, 1)">,
);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对象中</span>
let obj =<span style="color: rgba(0, 0, 0, 1)"> {
    first: </span>'Jane'<span style="color: rgba(0, 0, 0, 1)">,
    last: </span>'Doe'<span style="color: rgba(0, 0, 0, 1)">,
};

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数组中</span>
let arr =<span style="color: rgba(0, 0, 0, 1)"> [
    </span>'red'<span style="color: rgba(0, 0, 0, 1)">,
    </span>'green'<span style="color: rgba(0, 0, 0, 1)">,
    </span>'blue'<span style="color: rgba(0, 0, 0, 1)">,
];</span></pre>
</div>
<h2 id="ES9新特性(ECMAScript-2018)"><span style="font-size: 18px">ES9新特性</span></h2>
<p><span style="font-size: 18px"><span style="font-size: 14px">1.异步迭代器:异步迭代器对象的<strong>next()方法返回了一个Promise</strong>,解析后的值跟普通的迭代器类似。</span><br></span></p>
<div class="cnblogs_code">
<pre>async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> example() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 普通迭代器:</span>
const iterator =<span style="color: rgba(0, 0, 0, 1)"> createNumberIterator();
iterator.next(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 1, done: false}</span>
iterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 2, done: false}</span>
iterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 3, done: false}</span>
iterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: undefined, done: true}</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 异步迭代器:</span>
const asyncIterator =<span style="color: rgba(0, 0, 0, 1)"> createAsyncNumberIterator();
const p </span>= asyncIterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Promise</span>
<strong>await</strong> <strong>p</strong>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 1, done: false}</span>
await asyncIterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 2, done: false}</span>
await asyncIterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: 3, done: false}</span>
await asyncIterator.next(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object {value: undefined, done: true}</span>
}</pre>
</div>
<p><strong>2.&nbsp;&nbsp;Rest/Spread 属性</strong></p>
<pre><span class="line"><span class="line">rest参数和展开运算符,这项特性在ES6中已经引入,但是ES6中仅限于<strong>数组</strong>。在ES9中,为<strong>对象</strong>提供了像数组一样的rest参数和扩展运算符。<br></span></span></pre>
<div class="cnblogs_code">
<pre>const obj =<span style="color: rgba(0, 0, 0, 1)"> {
a: </span>1<span style="color: rgba(0, 0, 0, 1)">,
b: </span>2<span style="color: rgba(0, 0, 0, 1)">,
c: </span>3<span style="color: rgba(0, 0, 0, 1)">
}
const { a, ...param } </span>=<span style="color: rgba(0, 0, 0, 1)"> obj;
console.log(a)   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1</span>
console.log(param) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{b: 2, c: 3}</span>

<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> foo({a, ...param}) {
console.log(a);    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1</span>
console.log(param) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{b: 2, c: 3}</span>
}</pre>
</div>
<p>3.&nbsp;&nbsp;Promise.prototype.finally()</p>
<p>finally的回调总会被执行。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">promise
.then(result </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {···})
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(error =&gt;<span style="color: rgba(0, 0, 0, 1)"> {···})
.</span><span style="color: rgba(0, 0, 255, 1)">finally</span>(() =&gt; {···});</pre>
</div>
<p>4. 命名捕获组</p>
<p>ES9中可以通过名称来识别捕获组:</p>
<div class="cnblogs_code">
<pre>(?&lt;year&gt;{4})</pre>
</div>
<p>before:</p>
<div class="cnblogs_code">
<pre>const RE_DATE = /({4})-({2})-({2})/<span style="color: rgba(0, 0, 0, 1)">;

const matchObj </span>= RE_DATE.exec('1999-12-31'<span style="color: rgba(0, 0, 0, 1)">);
const year </span>= matchObj; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1999</span>
const month = matchObj; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 12</span>
const day = matchObj; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 31</span></pre>
</div>
<p>after:</p>
<div class="cnblogs_code">
<pre>const RE_DATE = /(?&lt;year&gt;{4})-(?&lt;month&gt;{2})-(?&lt;date&gt;{2})/<span style="color: rgba(0, 0, 0, 1)">;

const matchObj </span>= RE_DATE.exec('1999-12-31'<span style="color: rgba(0, 0, 0, 1)">);
const year </span>= matchObj.groups.year; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1999</span>
const month = matchObj.groups.month; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 12</span>
const day = matchObj.groups.date; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 31</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用解构语法更为简便</span>
const {groups: {day, year}} = RE_DATE.exec('1999-12-31'<span style="color: rgba(0, 0, 0, 1)">);
console.log(year); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1999</span>
console.log(day); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 31</span></pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;<span style="font-size: 18px">ES10新特性</span></p>
<p><strong><span style="font-size: 14px">1. 选择性的catch绑定</span></strong></p>
<p><span style="font-size: 14px">在使用try catch错误异常处理时,可以选择性的给catch传入参数(可以不给catch传参)</span></p>
<p><span style="font-size: 14px"><em>正常使用try catch:</em></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> do something</span>
} <span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log('err', err);</span>
}</pre>
</div>
<p>&nbsp;</p>
<p>在es10中使用时,可以:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> do something</span>
} <span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 128, 0, 1)">// do something</span></pre>
<pre>}</pre>
</div>
<p><strong><span style="font-size: 14px">2. JSON.superset</span></strong></p>
<p><span style="font-size: 14px">背景: JSON内容可以正常包含 <span style="color: rgba(255, 0, 0, 1)">行分隔符(\u2028)</span>和 <span style="color: rgba(255, 0, 0, 1)">段落分隔符(<span style="font-size: 14px">\u2029</span>)</span>而ECMAScript却不行。</span></p>
<p><span style="font-size: 14px">在ES10中,可以直接使用</span></p>
<div class="cnblogs_code">
<pre>eval('\u2029');</pre>
</div>
<p>&nbsp;</p>
<p>而不会在提示错误。</p>
<p><strong><span style="font-size: 14px">3. Symbol.prototype.description<br></span></strong></p>
<p><span style="font-size: 14px">为Symbol类型增加Symbol.prototype.description的一个访问器属性,用来获取Symbol类型数据的描述信息。</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>console.log(Symbol('test'<span style="color: rgba(0, 0, 0, 1)">).description);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'test'</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(Symbol.</span><span style="color: rgba(0, 0, 255, 1)">for</span>('test'<span style="color: rgba(0, 0, 0, 1)">).description);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'test'</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(Symbol.iterator.description);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'Symbol.iterator'</span></pre>
</div>
<p>&nbsp;</p>
<p><strong><span style="font-size: 14px">4. Function.prototype.toString</span></strong></p>
<p><span style="font-size: 14px">在ES10之后,函数调用toString()方法,将准确返回原有信息,包括空格和注释等。</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let funcToString = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">do something</span>
    console.log('test'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
"function () {
    //do something
    console.log('test');
}"
</span><span style="color: rgba(0, 128, 0, 1)">*/</span></pre>
</div>
<p>&nbsp;</p>
<p><strong><span style="font-size: 14px">5. Object.fromEntries()</span></strong></p>
<p><span style="font-size: 14px"><span style="font-size: 14px">Object.fromEntries()</span>是<span style="font-size: 14px">Object.entries()的反转。</span></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>const obj = { foo: 'bar', baz: 42<span style="color: rgba(0, 0, 0, 1)">}
let res1 </span>=<span style="color: rgba(0, 0, 0, 1)"> Object.entries(obj);
console.log(res1);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [['foo', 'bar'], ['baz', 42]]</span>
let obj1=<span style="color: rgba(0, 0, 0, 1)"> Object.fromEntries(res1);
console.log(obj1);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {foo: 'bar', baz: 42}</span></pre>
</div>
<p>&nbsp;</p>
<p>map转换为object</p>
<div class="cnblogs_code">
<pre>let map = <span style="color: rgba(0, 0, 255, 1)">new</span> Map([['name','alex'], ['age', 18<span style="color: rgba(0, 0, 0, 1)">]]);
const obj2 </span>=<span style="color: rgba(0, 0, 0, 1)"> Object.fromEntries(map);
console.log(obj2);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> object {name: 'alex', age: 18}</span></pre>
</div>
<p><strong><span style="font-size: 14px">6. 更友好的JSON.stringify</span></strong></p>
<p><span style="font-size: 14px">正常字符的表示不变:</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>JSON.stringify('𝌆'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> → '"𝌆"'</span>
JSON.stringify('\uD834\uDF06'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> → '"𝌆"'</span></pre>
</div>
<p>&nbsp;</p>
<p>而无法用 UTF-8 编码表示的字符会被序列化为转移序列:</p>
<div class="cnblogs_code">
<pre>JSON.stringify('\uDF06\uD834'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> → '"\\udf06\\ud834"'</span>
JSON.stringify('\uDEAD'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> → '"\\udead"'</span></pre>
</div>
<p><strong><span style="font-size: 14px">7. String.prototype.{trimStart, trimEnd}<br></span></strong></p>
<p><span style="font-size: 14px"><span style="font-size: 14px">trimStart()从字符串开头删除空格,返回一个新的字符串,不会修改原字符串。</span></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let str = '      hello, miss cecelia!';<span style="color: rgba(0, 0, 0, 1)">
console.log(str.trimStart());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 'hello, miss cecelia!'</span></pre>
</div>
<p>&nbsp;</p>
<p>trimEnd()从字符串右端开始移除空白字符,返回一个<span style="font-size: 14px"><span style="font-size: 14px">新的字符串,不会修改原字符串。</span></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let str = '      hello, miss cecelia!             ';<span style="color: rgba(0, 0, 0, 1)">
console.log(str.trimEnd());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> '      hello, miss cecelia!'</span></pre>
</div>
<p>&nbsp;</p>
<p><strong><span style="font-size: 14px">8. Array.prototype.{flat, flatMap}<br></span></strong></p>
<p><span style="font-size: 14px"><span style="font-size: 14px">Array.prototype.flat()可显式地传入参数,表示打平的层级。不传参数,表示只打平第一级。</span></span><strong><span style="font-size: 14px"><strong><span style="font-size: 14px"><br></span></strong></span></strong></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let arr = ]]];
console.log(arr.flat());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ]]</span>
console.log(arr.flat(2<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ]</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14px"><span style="font-size: 14px">flatMap()方法:可以看作flat和map组合在一起的结果:</span></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>['My dog', 'is awesome'].map(words =&gt; words.split(' '<span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [ [ 'My', 'dog' ], [ 'is', 'awesome' ] ]</span>
['My dog', 'is awesome'].flatMap(words =&gt; words.split(' '<span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">[ 'My', 'dog', 'is', 'awesome' ]</span></pre>
</div>
<p>&nbsp;ES 12 新特性</p>
<p>1. String.propotype.replaceAll</p>
<p>看到replaceAll这个词,相比很容易联想到replace。在JavaScript中,replace方法只能是替换字符串中匹配到的第一个实例字符,而不能进行全局多项匹配替换,唯一的办法是通过正则表达式进行相关规则匹配替换。</p>
<div class="cnblogs_code">
<pre>let string = ' I like apple. And I also like peach.'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用replace替换一次</span>
let replaceStr = string.replace('like', 'dislike'<span style="color: rgba(0, 0, 0, 1)">);
console.log(replaceStr);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> I dislike apple. And I also like peach.</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用replace替换全部</span>
let replaceStr2 = string.replace(/like/g, 'dislike'<span style="color: rgba(0, 0, 0, 1)">);
console.log(replaceStr2);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> I dislike apple. And I also dislike peach.</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用replaceAll 替换全部</span>
let replaceStr3 = string.replaceAll('like', 'dislike'<span style="color: rgba(0, 0, 0, 1)">);
console.log(replaceStr3);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> I dislike apple. And I also dislike peach.<br></span></pre>
<pre><span style="color: rgba(0, 128, 0, 1)">// 使用replaceAll +正则全局(g)替换全部</span></pre>
<p>  let replaceStr4 = string.replaceAll(/like/g, 'dislike');<br>  console.log(replaceStr4);</p>
<pre><span style="color: rgba(0, 128, 0, 1)">// 注意,在replaceAll 中使用正则表达式,必须要加/g, 否则会报错TypeError</span></pre>
</div>
<p>2. Promise.any()&nbsp;</p>
<p>当Promise数组中至少有一个返回了resolved Promise,就返回第一resolved Promise. 如果全部是rejected Promise, 则返回一个rejected Promise.(与Promise race比较,要等到第一resolved才返回结果,而不是第一有结果的Promise就返回)&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Promise.any([
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 500, 'jujue1'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(resolve, 1000, 'jieshou2'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(resolve, 1200, 'jieshou3'<span style="color: rgba(0, 0, 0, 1)">)),
    ]).then(value </span>=&gt; console.log('输出结果:'<span style="color: rgba(0, 0, 0, 1)">, value))
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(err =&gt; console.log(err))<span style="color: rgba(0, 128, 0, 1)">// 输出结果: jieshou2</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Promise.any([
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 500, 'jujue1'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 1000, 'jieshou2'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 200, 'jieshou3'<span style="color: rgba(0, 0, 0, 1)">)),
    ]).then(value </span>=&gt; console.log('输出结果:', value)).<span style="color: rgba(0, 0, 255, 1)">catch</span>(err =&gt; console.log('全部reject',err)) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 全部reject AggregateError: All promises were rejected</span></pre>
</div>
<p>对比Promise.race()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Promise.race([
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 500, 'jujue1'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(resolve, 1000, 'jieshou2'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(resolve, 1200, 'jieshou3'<span style="color: rgba(0, 0, 0, 1)">)),
    ]).then(value </span>=&gt; console.log('输出结果:', value)).<span style="color: rgba(0, 0, 255, 1)">catch</span>(err =&gt; console.log('reject结果',err))<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> reject结果 jujue1</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Promise.race([
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 500, 'jujue1'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 1000, 'jieshou2'<span style="color: rgba(0, 0, 0, 1)">)),
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =&gt; setTimeout(reject, 200, 'jieshou3'<span style="color: rgba(0, 0, 0, 1)">)),
    ]).then(value </span>=&gt; console.log('输出结果:', value)).<span style="color: rgba(0, 0, 255, 1)">catch</span>(err =&gt; console.log('reject结果',err)) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">reject结果 jieshou3</span></pre>
</div>
<p>3. WeakRef: 使用WeakRef的class类创建对对象的弱引用(当不存在对对象的其他引用时,不会阻止GC的回收行为)。具体的函数WeakSet() ,&nbsp; WeakMap()</p>
<p>WeakRef用在何处? 如使用map实现许多个<strong>需要大量内存</strong>的键值缓存,在这种情况下最方便的就是尽快释放键值对占用的内存。</p>
<p>例如: 使用方法追踪特定对象调用某个方法的次数,超过1000次提示.</p>
<div class="cnblogs_code">
<pre>let map = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Map();
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> doSomething() {
    ...
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> count(obj) {
    doSomething(obj);
    let num </span>= map.get(obj) || 0<span style="color: rgba(0, 0, 0, 1)">;
    num</span>++<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> ( num &gt; 1000<span style="color: rgba(0, 0, 0, 1)">) {
      console.log(</span>'当前对象调用次数超过1000次'<span style="color: rgba(0, 0, 0, 1)">);
    }
    map.set(obj, num)
}</span></pre>
</div>
<p>上述代码使用map, 虽然能够实现既定的功能,但是有可能会存在内容溢出(每个调用count的对象都会被永久保存在map中,这份引用一直存在,不会被GC回收)。</p>
<p>我们可以使用WeakMap</p>
<div class="cnblogs_code">
<pre>let wmap = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> WeakMap();
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> doSomething() {
    ...
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> count(obj) {
   doSomething();
    let num </span>= wmap.get(obj) || 0<span style="color: rgba(0, 0, 0, 1)">;
    num </span>++<span style="color: rgba(0, 0, 0, 1)"> ;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> ( num &gt; 1000<span style="color: rgba(0, 0, 0, 1)">) {
      console.log(</span>'当前对象调用次数超过1000次'<span style="color: rgba(0, 0, 0, 1)">);
    }
    wmap.set(obj, num);
}</span></pre>
</div>
<p>使用WeakMap的优势: 弱引用,如果没有其他引用,那么就可以被GC回收。</p>
<p>注意:WeakSet和WeakMap都是不可迭代的。</p>
<p>&nbsp;</p>
<p>4. 逻辑运算符和赋值表达式</p>
<div class="cnblogs_code">
<pre>a ||=<span style="color: rgba(0, 0, 0, 1)"> b
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 等价于</span>
a = a || (a =<span style="color: rgba(0, 0, 0, 1)"> b);

a </span>&amp;&amp;=<span style="color: rgba(0, 0, 0, 1)"> b
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 等价于</span>
a = a &amp;&amp; (a =<span style="color: rgba(0, 0, 0, 1)"> b);

a </span>??=<span style="color: rgba(0, 0, 0, 1)"> b
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 等价于</span>
a = a ?? (a = b);</pre>
</div>
<p>小结:</p>
<ul class="list-paddingleft-2">
<li>
<p>a ||= b:当a值不存在时,将b变量赋值给a</p>
</li>
<li>
<p>a &amp;&amp;= b:当a值存在时,将b变量赋值给a</p>
</li>
<li>
<p>a ??= b:当a值为null或者undefined时,将b变量赋值给a</p>
</li>
</ul>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/ceceliahappycoding/p/11354353.html
頁: [1]
查看完整版本: javaScript ES7 ES8 ES9 ES10 ES12新特性