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>