【译】六个漂亮的 ES6 技巧

   <p>在这篇文章里,我将演示 6 种 ES6 新特性的使用技巧。在每个段落的末尾,我会指出它们在我的书 <a href="/misc/goto?guid=4958969215922005852" rel="nofollow,noindex">Exploring ES6</a> 中的出处(你可以在线免费阅读这本书)。</p>    <h2>通过参数默认值强制要求传参</h2>    <p>ES6 指定默认参数在它们被实际使用的时候才会被执行,这个特性让我们可以强制要求传参:</p>    <pre>  <code class="language-actionscript">/** * Called if a parameter is missing and * the default value is evaluated. */  function mandatory() {      throw new Error("Missing parameter");  }  function foo(mustBeProvided = mandatory()) {      return mustBeProvided;  }  </code></pre>    <p>函数调用 mandatory() 只有在参数 mustBeProvided 缺失的时候才会被执行。</p>    <p>在控制台测试:</p>    <pre>  <code class="language-actionscript">> foo()  Error: Missing parameter  > foo(123)  123  </code></pre>    <p>更多内容:</p>    <ul>     <li>段落: “ <a href="/misc/goto?guid=4959674114206270744" rel="nofollow,noindex">Required parameters</a> ” 。</li>    </ul>    <h2>通过 for-of 循环来遍历数组元素和索引</h2>    <p>方法 forEach() 允许你遍历一个数组的元素和索引:</p>    <pre>  <code class="language-actionscript">var arr = ["a", "b", "c"];  arr.forEach(function (elem, index) {      console.log("index = "+index+", elem = "+elem);  });  // Output:  // index = 0, elem = a  // index = 1, elem = b  // index = 2, elem = c  </code></pre>    <p>ES6 的 for-of 循环支持 ES6 迭代(通过 iterables 和 iterators)和解构。如果你通过数组的新方法 enteries() 再结合解构,可以达到上面 forEach 同样的效果:</p>    <pre>  <code class="language-actionscript">const arr = ["a", "b", "c"];  for (const [index, elem] of arr.entries()) {      console.log(`index = ${index}, elem = ${elem}`);  }  </code></pre>    <p>arr.enteries() 通过索引-元素配对返回一个可迭代对象。然后通过解构数组 [index, elem] 直接得到每一对元素和索引。 console.log() 的参数是 ES6 中的模板字面量特性,这个特性带给字符串解析模板变量的能力。</p>    <p>更多内容:</p>    <ul>     <li>章节: “ <a href="/misc/goto?guid=4959674114283613404" rel="nofollow,noindex">Destructuring</a> ”</li>     <li>章节: “ <a href="/misc/goto?guid=4959674114370898058" rel="nofollow,noindex">Iterables and iterators</a> ”</li>     <li>段落: “ <a href="/misc/goto?guid=4959674114442800813" rel="nofollow,noindex">Iterating with a destructuring pattern</a> ”</li>     <li>章节: “ <a href="/misc/goto?guid=4959674114529462403" rel="nofollow,noindex">Template literals</a> ”</li>    </ul>    <h2>遍历 Unicode 表示的字符串</h2>    <p>一些 Unicode 编码的字由两个 JavaScript 字符组成,例如,emoji 表情:</p>    <p><img src="https://simg.open-open.com/show/acdc40e262ea1074177f06edf634c141.png"></p>    <p>字符串实现了 ES6 迭代,如果你通过迭代来访问字符串,你可以获得编码过的单个字(每个字用 1 或 2 个 JavaScript 字符表示)。例如:</p>    <pre>  <code class="language-actionscript">for (const ch of "x\uD83D\uDE80y") {      console.log(ch.length);  }  // Output:  // 1  // 2  // 1  </code></pre>    <p>这让你能够很方便地得到一个字符串中实际的字数:</p>    <pre>  <code class="language-actionscript">> [..."x\uD83D\uDE80y"].length  3  </code></pre>    <p>展开操作符 ( ... ) 将它的操作对象展开并插入数组。</p>    <p>更多内容:</p>    <ul>     <li>章节: “ <a href="/misc/goto?guid=4959674114604990833" rel="nofollow,noindex">Unicode in ES6</a> ”</li>     <li>段落: “ <a href="/misc/goto?guid=4959674114692028415" rel="nofollow,noindex"> The spread operator ( ... ) </a> ”</li>    </ul>    <h2>通过变量解构交换两个变量的值</h2>    <p>如果你将一对变量放入一个数组,然后将数组解构赋值相同的变量(顺序不同),你就可以不依赖中间变量交换两个变量的值:</p>    <pre>  <code class="language-actionscript">[a, b] = [b, a];  </code></pre>    <p>可以想象,JavaScript 引擎在未来将会针对这个模式进行特别优化,去掉构造数组的开销。</p>    <p>更多内容:</p>    <ul>     <li>章节: “ <a href="/misc/goto?guid=4959674114283613404" rel="nofollow,noindex">Destructuring</a> ”</li>    </ul>    <h2>通过模板字面量(template literals)进行简单的模板解析</h2>    <p>ES6 的模板字面量与文字模板相比,更接近于字符串字面量。但是,如果你将它们通过函数返回,你可以使用他们来做简单的模板渲染:</p>    <pre>  <code class="language-actionscript">const tmpl = addrs => `      <table>      ${addrs.map(addr => `          <tr><td>${addr.first}</td></tr>          <tr><td>${addr.last}</td></tr>      `).join("")}      </table>  `;  </code></pre>    <p>tmpl 函数将数组 addrs 用 map (通过 <a href="/misc/goto?guid=4959674114775498845" rel="nofollow,noindex">箭头函数</a> ) join 拼成字符串。 tmpl() 可以批量插入数据到表格中:</p>    <pre>  <code class="language-actionscript">const data = [      { first: "<Jane>", last: "Bond" },      { first: "Lars", last: "<Croft>" },  ];  console.log(tmpl(data));  // Output:  // <table>  //  // <tr><td><Jane></td></tr>  // <tr><td>Bond</td></tr>  //  // <tr><td>Lars</td></tr>  // <tr><td><Croft></td></tr>  //  // </table>  </code></pre>    <p>更多内容:</p>    <ul>     <li>博客文章: “ <a href="/misc/goto?guid=4959674114859345587" rel="nofollow,noindex">Handling whitespace in ES6 template literals</a> ”</li>     <li>段落: “ <a href="/misc/goto?guid=4959674114938622961" rel="nofollow,noindex">Text templating via untagged template literals</a> ”</li>     <li>章节: “ <a href="/misc/goto?guid=4959674114775498845" rel="nofollow,noindex">Arrow functions</a> ”</li>    </ul>    <h2>通过子类工厂实现简单的合成器</h2>    <p>当 ES6 类继承另一个类,被继承的类可以是通过任意表达式创建的动态类:</p>    <pre>  <code class="language-actionscript">// Function id() simply returns its parameter  const id = x => x;    class Foo extends id(Object) {}  </code></pre>    <p>这个特性可以允许你实现一种合成器模式,用一个函数来将一个类 C 映射到一个新的继承了 C 的类。例如,下面的两个函数 Storage 和 Validation 是合成器:</p>    <pre>  <code class="language-actionscript">const Storage = Sup => class extends Sup {      save(database) { ··· }  };  const Validation = Sup => class extends Sup {      validate(schema) { ··· }  };  </code></pre>    <p>你可以使用它们去组合生成一个如下的 Employee 类:</p>    <pre>  <code class="language-actionscript">class Person { ··· }  class Employee extends Storage(Validation(Person)) { ··· }  </code></pre>    <p>更多信息:</p>    <ul>     <li>段落: “ <a href="/misc/goto?guid=4959674115031565931" rel="nofollow,noindex">Simple mixins</a> ”</li>    </ul>    <h2>进一步阅读</h2>    <p>下面的两个章节提供了很好地概括了 ECMAScript 6 的特性:</p>    <ul>     <li><a href="/misc/goto?guid=4959674115117796731" rel="nofollow,noindex">An overview of what’s new in ES6</a></li>     <li><a href="/misc/goto?guid=4959674115188719585" rel="nofollow,noindex">First steps with ECMAScript 6</a> [features that are easy to adopt]</li>    </ul>    <p> </p>    <p>来自: <a href="/misc/goto?guid=4959674115275273132" rel="nofollow">https://www.h5jun.com/post/six-nifty-es6-tricks.html</a></p>    <p> </p>