LoginSignup
0
0

More than 5 years have passed since last update.

変数スコープは複製できない

Last updated at Posted at 2017-07-12

JavaScriptでオブジェクトを複製してその中の関数を使ったら想定外の挙動をしてしまいました。

なんか初歩的な話のような気がするけど・・・
(コメントを受けて質問は削除しました備忘録という事にします)

ソース1

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
  <script src="test.js"></script>
</head>
<body>
</body>
</html>
test.js
var baseObject = baseFunction();

function baseFunction () {
  var _id = null;

  function setId (id) {
    _id = id;
  }

  function getId () {
    return _id;
  }

  return {
    setId: setId,
    getId: getId
  }
}

// baseObjectを複製
var object1 = {};
var object2 = {};
$.extend(true, object1, baseObject);
$.extend(true, object2, baseObject);

console.log("start▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼");

console.log(object1.getId());
console.log(object2.getId());

object1.setId(1);
console.log("object1 set/////////////////");

console.log(object1.getId());
console.log(object2.getId());

object2.setId(2);
console.log("object2 set/////////////////");

console.log(object1.getId());
console.log(object2.getId());

console.log("end▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲");

予想

"start▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼"
null
null
"object1 set/////////////////"
1
null
"object2 set/////////////////"
1
2
"end▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲"

結果

"start▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼"
null
null
"object1 set/////////////////"
1
1
"object2 set/////////////////"
2
2
"end▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲"

このような結果になるのが分からなくて悩みました。
とりあえず以下のようにしたら思い通りになったので良かったのですが、よくわかりません。
追記:スコープは複製できないという事のようです
上記のパターンを使うことがあれば気を付けようと思いました。

ソース2

test.js
function baseFunction () {
  var _id = null;

  function setId (id) {
    _id = id;
  }

  function getId () {
    return _id;
  }

  return {
    setId: setId,
    getId: getId
  }
}

var object1 = baseFunction();
var object2 = baseFunction();

console.log("start▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼");

console.log(object1.getId());
console.log(object2.getId());

object1.setId(1);
console.log("object1 set/////////////////");

console.log(object1.getId());
console.log(object2.getId());

object2.setId(2);
console.log("object2 set/////////////////");

console.log(object1.getId());
console.log(object2.getId());

console.log("end▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲");

結果

start▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
null
null
object1 set/////////////////
1
null
object2 set/////////////////
1
2
end▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0