JavaScript【 array 】8 ~ 配列のコピー

Various chocolate truffle candies in a box on gray stone background

JavaScriptでは、配列はオブジェクトの1つです。オブジェクトをそのままコピーすると、その後の処理で意図した結果を得られなくなる場合があるので、配列変数をコピーする際には注意が必要です。
今回は、このような配列のコピーについて紹介します。

目次

 
1.オブジェクトの参照渡し
2.配列をそのまま参照コピー
3.concatメソッドでコピー
4.sliceメソッドでコピー
 

1.オブジェクトの参照渡し

 
JavaScriptでは、配列はオブジェクトの1つです。

オブジェクトは、複数の値をひとまとめにしたもの というイメージです。
そう考えると、1つの配列には、通常、複数の要素があるので、配列がオブジェクトであるということは理解し易いかと思います。

変数をコピーして複製を作る場合、オブジェクトは、文字列や数値等の値とは異なる特徴があります。

文字列等、オブジェクト以外の変数のコピーは、「 値渡し 」と言い、コピーのイメージ通り、元の変数の中の値が、コピー先の変数に代入されます。

これに対し、オブジェクトのコピーは、「 参照渡し 」と言い、元の変数のアドレスがコピー先の変数に渡されます。

オブジェクト変数obj1をobj2にコピーすると、obj1のアドレスがobj2に渡されて、obj1もobj2も、同じ中身(複数の値)を捉えているイメージです。
7096colmun_image6280_01

▲目次へ戻る

 

2.配列をそのまま参照コピー

 
配列を、そのままコピーしてみます。

var fruits1 =  ["りんご", "みかん", "ぶどう", "メロン", "もも"];
var fruits2 =  fruits1;

それぞれの中身を見てみましょう。
ボタンをクリックしてみて下さい。

  

 

  

ここまでは、コピーのイメージそのままの結果です。
 
次に、fruits2の中の値を変更してみます。
2番目の値の「みかん」を「レモン」に変更します。

var fruits1 =  ["りんご", "みかん", "ぶどう", "メロン", "もも"];
var fruits2 =  fruits1;

fruits2[1] = "レモン";

2つの変数の中身を見てみましょう。
ボタンをクリックしてみて下さい。

  

 

  

fruits2の2番目の値の「みかん」を「レモン」に変更すると、fruits1の2番目の値も、「みかん」から「レモン」に変わります。

1.オブジェクトの参照渡しで紹介した通り、fruits1もfruits2も、同じデータを扱っているため、fruits2でデータの変更を行うと、以後、fruits1でも変更後のデータを扱っていくことになります。

▲目次へ戻る

 

3.concatメソッドでコピー

 
先ほどの参照コピーをすると、多くの場合、意図した後続処理ができないと考えられます。

やはり、配列のコピーを行う際も、値の1つ1つが複製されることを念頭に置いているのではないでしょうか。
concatメソッドを使用して配列のコピーを行うと、それが実現できます。

concatメソッドは、Arrayオブジェクトで用意されているメソッドで、2つの配列を連結した新しい配列を返すためのメソッドです。
(Arrayオブジェクトについては、Arrayオブジェクトとはをご参照下さい。)

concatメソッドを使用して配列をコピーする場合は、次のように記述します。

var コピー元変数 = [値1, 値2, 値3, ...];

var コピー先変数 =  コピー元変数 .concat( );

 
concatメソッドを使用して配列をコピーした後、コピー先の配列の値を変更してみます。
ボタンをクリックしてそれぞれのデータを確認してみて下さい。

fruits1 = [“りんご”, “みかん”, “ぶどう”, “メロン”, “ぶどう”, “もも”];
fruits2 = fruits1.concat();
fruits2[1] = “レモン”;

上記を実行した後の各配列のデータを表示します

  

 

  

 
ソースコードは次の通りです。

<script type="text/javascript">
<!--
var fruits1 =  ["りんご", "みかん", "ぶどう", "メロン", "もも"];
var fruits2 =  fruits1.concat();

fruits2[1] = "レモン";

function dispAry() {
    document.getElementById("dat").value = fruits1;
}

function dispAry2() {
    document.getElementById("dat2").value = fruits2;
}
//-->
</script>

<div style="background-color : #CCC; padding : 20px;">
    fruits1 = ["りんご", "みかん", "ぶどう", "メロン", "ぶどう", "もも"];
    fruits2 = fruits1.concat();
    fruits2[1] = "レモン";

    上記を実行した後の各配列のデータを表示します
    <form>
        <div style="display:inline-flex;">
           <input type="button" value="fruits1のデータ" onClick="dispAry()"> 
            <input type="text" id="dat" placeholder="ここに表示します" size="40">
        </div>
 
        <div style="display:inline-flex;">
           <input type="button" value="fruits2のデータ" onClick="dispAry2()"> 
            <input type="text" id="dat2" placeholder="ここに表示します" size="40">
        </div>
    </form>
</div>

fruits2はfruits1をコピーして作成した配列ですが、違うアドレスを持った別の配列となるため、fruits2の中のデータを変更しても、fruits1に影響は及びません。

▲目次へ戻る

 

4.sliceメソッドでコピー

 
concatメソッドを使用したコピーと同様に、sliceメソッドを使用しても、値の1つ1つを複製した配列のコピーを行うことができます。

sliceメソッドは、Arrayオブジェクトで用意されているメソッドで、配列の一部を返すためのメソッドです。
(Arrayオブジェクトについては、Arrayオブジェクトとはをご参照下さい。)

sliceメソッドを使用して配列をコピーする場合は、次のように記述します。

var コピー元変数 = [値1, 値2, 値3, ...];

var コピー先変数 =  コピー元変数 .slice( );

 
sliceメソッドを使用して配列をコピーした後、コピー先の配列の値を変更してみます。
ボタンをクリックしてそれぞれのデータを確認してみて下さい。

fruits1 = [“りんご”, “みかん”, “ぶどう”, “メロン”, “ぶどう”, “もも”];
fruits2 = fruits1.slice();
fruits2[2] = “キウイ”;

上記を実行した後の各配列のデータを表示します

  

 

  

 
ソースコードは次の通りです。

<script type="text/javascript">
<!--
var fruits1 =  ["りんご", "みかん", "ぶどう", "メロン", "もも"];
var fruits2 =  fruits1.slice();

fruits2[2] = "キウイ";

function dispAry() {
    document.getElementById("dat").value = fruits1;
}

function dispAry2() {
    document.getElementById("dat2").value = fruits2;
}
//-->
</script>

<div style="background-color : #CCC; padding : 20px;">
    fruits1 = ["りんご", "みかん", "ぶどう", "メロン", "ぶどう", "もも"];
    fruits2 = fruits1.slice();
    fruits2[2] = "キウイ";

    上記を実行した後の各配列のデータを表示します
    <form>
        <div style="display:inline-flex;">
           <input type="button" value="fruits1のデータ" onClick="dispAry()"> 
            <input type="text" id="dat" placeholder="ここに表示します" size="40">
        </div>
 
        <div style="display:inline-flex;">
           <input type="button" value="fruits2のデータ" onClick="dispAry2()"> 
            <input type="text" id="dat2" placeholder="ここに表示します" size="40">
        </div>
    </form>
</div>

concatメソッドと同様に、sliceメソッドを使用して配列のコピーを行っても、fruits2のデータ変更は、fruits1に影響を及ぼしません。

▲目次へ戻る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です