Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1131569 of Array.prototype.copyWithin()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Array/copyWithin
  • Revision title: Array.prototype.copyWithin()
  • Revision id: 1131569
  • Created:
  • Creator: fscholz
  • Is current revision? Yes
  • Comment

Revision Content

{{JSRef}}

The copyWithin() method shallow copies part of an array to another location in the same array and returns it, without modifying its size.

["alpha", "bravo", "charlie", "delta"].copyWithin(2, 0);

// results in ["alpha", "bravo", "alpha", "bravo"]

Syntax

arr.copyWithin(target[, start[, end]])

Parameters

target
Zero based index at which to copy the sequence to. If negative, target will be counted from the end.
If target is at or greater than arr.length, nothing will be copied. If target is positioned after start, the copied sequence will be trimmed to fit arr.length.
start {{optional_inline}}
Zero based index at which to start copying elements from. If negative, start will be counted from the end.
If start is omitted, copyWithin will copy from the start (defaults to 0).
end {{optional_inline}}
Optional. Zero based index at which to end copying elements from. copyWithin copies up to but not including end. If negative, end will be counted from the end.
If end is omitted, copyWithin will copy until the end (default to arr.length).

Return value

The modified array.

Description

The copyWithin works like C and C++'s memcpy, and is a high-performance method to shift the data of an {{jsxref("Array")}}. This especially applies to the {{jsxref("TypedArray/copyWithin", "TypedArray")}} method of the same name. The sequence is copied and pasted as one operation; pasted sequence will have the copied values even when the copy and paste region overlap.

The copyWithin function is intentionally generic, it does not require that its this value be an {{jsxref("Array")}} object.

The copyWithin method is a mutable method. It does not alter the length of this, but will change its content and create new properties if necessary.

Examples

[1, 2, 3, 4, 5].copyWithin(-2);
// [1, 2, 3, 1, 2]

[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]

[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}

// ES6 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);

i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]

// On platforms that are not yet ES6 compliant: 
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]

Polyfill

if (!Array.prototype.copyWithin) {
  Array.prototype.copyWithin = function(target, start/*, end*/) {
    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length >>> 0;

    // Steps 6-8.
    var relativeTarget = target >> 0;

    var to = relativeTarget < 0 ?
      Math.max(len + relativeTarget, 0) :
      Math.min(relativeTarget, len);

    // Steps 9-11.
    var relativeStart = start >> 0;

    var from = relativeStart < 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 12-14.
    var end = arguments[2];
    var relativeEnd = end === undefined ? len : end >> 0;

    var final = relativeEnd < 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 15.
    var count = Math.min(final - from, len - to);

    // Steps 16-17.
    var direction = 1;

    if (from < to && to < (from + count)) {
      direction = -1;
      from += count - 1;
      to += count - 1;
    }

    // Step 18.
    while (count > 0) {
      if (from in O) {
        O[to] = O[from];
      } else {
        delete O[to];
      }

      from += direction;
      to += direction;
      count--;
    }

    // Step 19.
    return O;
  };
}

Specifications

Specification Status Comment
{{SpecName('ES6', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}} {{Spec2('ES6')}} Initial definition.
{{SpecName('ES7', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}} {{Spec2('ES7')}}  
{{SpecName('ESDraft', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}} {{Spec2('ESDraft')}}  

Browser compatibility

{{CompatibilityTable}}
Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{CompatChrome("45")}} 12 {{CompatGeckoDesktop("32")}} {{CompatNo}} 32 9.0
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatNo}} {{CompatNo}} {{CompatGeckoMobile("32")}} {{CompatNo}} {{CompatNo}} {{CompatNo}}

See also

  • {{jsxref("Array")}}

Revision Source

<div>{{JSRef}}</div>

<p>The <code><strong>copyWithin()</strong></code> method shallow copies part of an array to another location in the same array and returns it, without modifying its size.</p>

<pre class="brush: js">
["alpha", "bravo", "charlie", "delta"].copyWithin(2, 0);

// results in ["alpha", "bravo", "alpha", "bravo"]
</pre>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox">
<var>arr</var>.copyWithin(<var>target</var>[, <var>start</var>[, <var>end</var>]])</pre>

<h3 id="Parameters">Parameters</h3>

<dl>
 <dt><code>target</code></dt>
 <dd>Zero based index at which to copy the sequence to. If negative, <code>target</code> will be counted from the end.</dd>
 <dd>If <code>target</code> is at or greater than <code>arr.length</code>, nothing will be copied. If <code>target</code> is positioned after <code>start</code>, the copied sequence will be trimmed to fit <code>arr.length</code>.</dd>
 <dt><code>start</code> {{optional_inline}}</dt>
 <dd>Zero based index at which to start copying elements from. If negative, <code>start</code> will be counted from the end.</dd>
 <dd>If <code>start</code> is omitted, <code>copyWithin</code> will copy from the start (defaults to 0).</dd>
 <dt><code>end</code> {{optional_inline}}</dt>
 <dd>Optional. Zero based index at which to end copying elements from. <code>copyWithin</code> copies up to but not including <code>end</code>. If negative, <code>end</code> will be counted from the end.</dd>
 <dd>If <code>end</code> is omitted, <code>copyWithin</code> will copy until the end (default to <code>arr.length</code>)<code>.</code></dd>
</dl>

<h3 id="Return_value">Return value</h3>

<p>The modified array.</p>

<h2 id="Description">Description</h2>

<p>The <code>copyWithin</code> works like C and C++'s <code>memcpy</code>, and is a high-performance method to shift the data of an {{jsxref("Array")}}. This especially applies to the {{jsxref("TypedArray/copyWithin", "TypedArray")}} method of the same name. The sequence is copied and pasted as one operation; pasted sequence will have the copied values even when the copy and paste region overlap.</p>

<p>The <code>copyWithin</code> function is intentionally <em>generic</em>, it does not require that its this value be an {{jsxref("Array")}} object.</p>

<p>The <code>copyWithin</code> method is a mutable method. It does not alter the length of <code>this</code>, but will change its content and create new properties if necessary.</p>

<h2 id="Examples">Examples</h2>

<pre class="brush: js">
[1, 2, 3, 4, 5].copyWithin(-2);
// [1, 2, 3, 1, 2]

[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]

[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}

// ES6 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);

i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]

// On platforms that are not yet ES6 compliant: 
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
</pre>

<h2 id="Polyfill">Polyfill</h2>

<pre class="brush: js">
if (!Array.prototype.copyWithin) {
  Array.prototype.copyWithin = function(target, start/*, end*/) {
    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length &gt;&gt;&gt; 0;

    // Steps 6-8.
    var relativeTarget = target &gt;&gt; 0;

    var to = relativeTarget &lt; 0 ?
      Math.max(len + relativeTarget, 0) :
      Math.min(relativeTarget, len);

    // Steps 9-11.
    var relativeStart = start &gt;&gt; 0;

    var from = relativeStart &lt; 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 12-14.
    var end = arguments[2];
    var relativeEnd = end === undefined ? len : end &gt;&gt; 0;

    var final = relativeEnd &lt; 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 15.
    var count = Math.min(final - from, len - to);

    // Steps 16-17.
    var direction = 1;

    if (from &lt; to &amp;&amp; to &lt; (from + count)) {
      direction = -1;
      from += count - 1;
      to += count - 1;
    }

    // Step 18.
    while (count &gt; 0) {
      if (from in O) {
        O[to] = O[from];
      } else {
        delete O[to];
      }

      from += direction;
      to += direction;
      count--;
    }

    // Step 19.
    return O;
  };
}
</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES7', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ES7')}}</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td>&nbsp;</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<div>{{CompatibilityTable}}</div>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Edge</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatChrome("45")}}</td>
   <td>12</td>
   <td>{{CompatGeckoDesktop("32")}}</td>
   <td>{{CompatNo}}</td>
   <td>32</td>
   <td>9.0</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoMobile("32")}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="See_also">See also</h2>

<ul>
 <li>{{jsxref("Array")}}</li>
</ul>
Revert to this revision