JavaScript 数组:对比 slice 与 splice

hubuke 8年前
   <p>对于 JavaScript 语言来讲,入门者甚至是专家都会经常搞不清 <code>slice</code> 和 <code>splice</code> 这两个方法。它们虽然名称<strong>相似</strong>,但是功能却<strong>完全不同</strong>。在使用中,可以通过选择一个具有强语义表达性的 API 来减少混淆的发生。</p>    <p>数组的 <code>slice</code> (ECMAScript 5.1 标准 <a href="/misc/goto?guid=4959677114095823766">15.4.4.10</a> 节)非常类似于字符串的 <code>slice</code>。根据规范,<code>slice</code> 需要两个参数,<em>起点</em>和<em>终点</em>。它会返回一个包含了从起点开始,到终点之前之间所有元素的<strong>新数组</strong>。理解 slice 的功能并不是太难:</p>    <pre>  <code class="language-javascript">'abc'.slice(1,2)           // "b"  [14, 3, 77].slice(1, 2)    //  [3]</code></pre>    <p>需要特别注意的是它<strong>并不会修改</strong>原数组。下面的代码段描述了这个行为,<em>x</em> 的值没有变,<em>y</em> 则是被截取的部分。</p>    <pre>  <code class="language-javascript">var x = [14, 3, 77];  var y = x.slice(1, 2);  console.log(x);          // [14, 3, 77]  console.log(y);          // [3]</code></pre>    <p>虽然 <code>splice</code>(<a href="/misc/goto?guid=4959677114185707672">15.4.4.12</a> 节)也需要(至少)两个参数,但它的意义则完全不同。</p>    <pre>  <code class="language-javascript">[14, 3, 77].slice(1, 2)     //  [3]  [14, 3, 77].splice(1, 2)    //  [3, 77]</code></pre>    <p>除此之外,<code>splice</code> 还会<strong>改变</strong>原数组。不要太惊讶,这正是 <em>splice</em> 的本意。</p>    <pre>  <code class="language-javascript">var x = [14, 3, 77]  var y = x.splice(1, 2)  console.log(x)           // [14]  console.log(y)           // [3, 77]</code></pre>    <p>当你编写自己的模块时,选择一个最不容易发生混淆的 API 非常重要。理论上,你的用户不应该总是通过阅读文档来判断他们需要哪一个。那么我们应该遵循哪种命名规范呢?</p>    <p>我最熟悉的规范(与我之前在 QT 上的经验有关)是正确地选择动词:现在时表示可能的修改行为,过去时则不会修改原对象,而是返回一个新的版本。如果可以的话,这两种版本都要提供。参考下面的例子:</p>    <pre>  <code class="language-javascript">var p = new Point(100, 75);  p.translate(25, 25);  console.log(p);       // { x: 125, y: 100 }    var q = new Point(200, 100);  var s = q.translated(10, 50);  console.log(q);       // { x: 200, y: 100 }  console.log(s);       // { x: 210, y: 150 }</code></pre>    <p>注意(在二维笛卡尔坐标系中)移动位置的 <code>translate()</code> 和仅创建一个移动过的坐标的 <code>translated()</code> 之间的区别。调用 <code>translate</code> 会修改点 <em>p</em> 的值。然而,因为 <code>translated()</code> <strong>不修改</strong>原对象,对象 <em>q</em> 没有被修改,而只返回了一个<strong>新的拷贝</strong> <em>s</em>。</p>    <p>如果这个规范能够非常一致地部署到你的应用中,那么上面提到的那种混淆则会被最大化地减低。有一天,你会让你的用户高兴地喊出<em>我终于明白了</em>!</p>    <p> 来自:http://www.zcfy.cc/article/javascript-array-slice-vs-splice-1036.html</p>