aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/array/copywithin/index.html
blob: b19fa2fc5653923d7fb75950cacd90b9973267da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
---
title: Array.prototype.copyWithin()
slug: Web/JavaScript/Reference/Global_Objects/Array/copyWithin
tags:
  - ECMAScript 2015
  - JavaScript
  - polyfill
  - 原型
  - 数组
  - 方法
translation_of: Web/JavaScript/Reference/Global_Objects/Array/copyWithin
---
<div>{{JSRef}}</div>

<div><code><strong>copyWithin()</strong></code> 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。</div>

<div>{{EmbedInteractiveExample("pages/js/array-copywithin.html")}}</div>



<h2 id="语法">语法</h2>

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

<h3 id="Parameters" name="Parameters">参数</h3>

<dl>
 <dt><code>target</code></dt>
 <dd>0 为基底的索引,复制序列到该位置。如果是负数,<code>target</code> 将从末尾开始计算。</dd>
 <dd>如果 <code>target</code> 大于等于 <code>arr.length</code>,将会不发生拷贝。如果 <code>target</code><code>start</code> 之后,复制的序列将被修改以符合 <code>arr.length</code></dd>
 <dt><code>start</code></dt>
 <dd>0 为基底的索引,开始复制元素的起始位置。如果是负数,<code>start</code> 将从末尾开始计算。</dd>
 <dd>如果 <code>start</code> 被忽略,<code>copyWithin</code> 将会从0开始复制。</dd>
 <dt><code>end</code></dt>
 <dd>0 为基底的索引,开始复制元素的结束位置。<code>copyWithin</code> 将会拷贝到该位置,但不包括 <code>end</code> 这个位置的元素。如果是负数, <code>end</code> 将从末尾开始计算。</dd>
 <dd>如果 <code>end</code> 被忽略,<code>copyWithin</code> 方法将会一直复制至数组结尾(默认为 <code>arr.length</code>)。</dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>改变后的数组。</p>

<h2 id="描述">描述</h2>

<p>参数 target、start 和 end 必须为整数。</p>

<p>如果 start 为负,则其指定的索引位置等同于 length+start,length 为数组的长度。end 也是如此。</p>

<p>copyWithin 方法不要求其 this 值必须是一个数组对象;除此之外,copyWithin 是一个可变方法,它可以改变 this 对象本身,并且返回它,而不仅仅是它的拷贝。</p>

<p><code>copyWithin</code> 就像 C 和 C++ 的 <code>memcpy</code> 函数一样,且它是用来移动 {{jsxref("Array")}} 或者 {{jsxref("TypedArray")}} 数据的一个高性能的方法。复制以及粘贴序列这两者是为一体的操作;即使复制和粘贴区域重叠,粘贴的序列也会有拷贝来的值。</p>

<p><code>copyWithin</code><strong> </strong>函数被设计为通用式的,其不要求其 <code>this</code> 值必须是一个{{jsxref("Array", "数组")}}对象。</p>

<p><code>copyWithin</code> 是一个可变方法,它不会改变 this 的长度 length,但是会改变 this 本身的内容,且需要时会创建新的属性。</p>

<h2 id="例子">例子</h2>

<pre><code>[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]</code>

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

// ES2015 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 ES2015 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="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">备注</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES2016', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ES2016')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-array.prototype.copywithin', 'Array.prototype.copyWithin')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>



<p>{{Compat("javascript.builtins.Array.copyWithin")}}</p>

<h2 id="参见">参见</h2>

<ul>
 <li>{{jsxref("Array")}}</li>
</ul>