JavaScriptのプリミティブ型とオブジェクトのコピーの違い

JavaScriptのプリミティブ型の値とオブジェクトをコピーしたときの違いについてまとめました。

プリミティブ型

プリミティブ型をコピーすると値そのものがコピーされる。

var a = 0

// aを変数bにコピーする
var b = a
console.log(b); // 0

// aの値を変更する
a = 1
console.log(a); // 1

// aの値を変更してもbの値に影響はない
console.log(b); // 0

プリミティブ型は値そのものがコピーされるので、コピー先で値を変更してもコピー元に影響はない。


関数の引数も同様。

let a = 0;

function fn(b) {
    // 2.渡されたaをbとして受け取り、aが格納されているbの値を変更する
    b = 1

    // 3.aの値に影響はなく、bだけが変更される
    console.log(a) // 0
    console.log(b) // 1
}

// 1.変数aを関数fnに渡す
fn(a)


オブジェクトのコピー

オブジェクトをコピーすると参照がコピーされる。

// nameプロパティを持つオブジェクトを定義する
let a = {
    name: 'obj'
}

// オブジェクトを格納している変数aをbにコピーする
let b = a

console.log(b) // {name: 'obj'}

// nameプロパティを変更する
a.name = 'a'

console.log(a) // {name: 'a'}
// bのオブジェクトのnameプロパティも変更されている、つまり同じ変数aのオブジェクトと変数bのオブジェクトは同じオブジェクトを指している
console.log(b) // {name: 'a'}

オブジェクトをコピーすると、値そのものではなく参照がコピーされるのでコピー元もコピー先も同じ値を指すことになる。そのためコピー先の値を変更するとコピー元の値にも影響がある。


関数の引数も同様。

let a = {
    name: 'a'
};

function fn(b) {
    // 2.渡されたaをbとして受け取り、nameプロパティを変更する
    b.name = 'b'

    // 3.コピー元の変数aのオブジェクトのnameプロパティも変更される
    console.log(a) // {name: 'b'}
    console.log(b) // {name: 'b'}
}

// 1.オブジェクトを格納する変数aを引数に渡す
fn(a)


ちなみに新しいオブジェクトを格納すると、参照先は新しいオブジェクトになるので、別のオブジェクトを指すことになる。

let a = {
    name: 'obj'
}

let b = a
console.log(b); // {name: 'obj'}

// 新しいオブジェクトを格納する
b = {}

// aのオブジェクトに影響はない
console.log(a); // {name: 'obj'}
console.log(b); // {}