본문 바로가기
바닐라코딩 사전학습/코드연습, 퀴즈, 과제

Primitive / Reference 퀴즈

by 꼬마보노 2021. 12. 27.

Q1)

const person = {
  age: 30
};

const something = person.age;

person.age = 50;

console.log(something); // ?

예상 답 : 30
예상 이유 : person은 참조형타입인 객체이고 person.age는 원시타입인 숫자이다. 따라서 sometihg에도 원시타입인 30이 저장되고 이후에 person.age값이 바뀌어도 따라서 바뀌지 않는다.
정답 : 30

 

Q2)

let one = { name: "one" };
const two = { name: "two" };

const something = one;

one = { name: "ONE" };

console.log(something); // ?

예상 답 : "ONE:
예상 이유 : const something를 선언 후에 one에 저장되어 있는 객체의 주소를 할당하였다. 이후에 one에 저장된 객체의 속성값을 바꾸었으므로 something이 가리키고 있는 값도 바뀌게 된다.
const는 변수의 타입과 값 모두 변경이 불가능하도록 선언하는 예약어이다. something에 저장 된 값은 one객체의 주소정보이기 때문에 위의 문제는 에러가 발생하지 않는다. something의 값 자체를 바꾸는 것이 아니기 때문.
정답 : {name: "one"}


오답 이유 : 우선 something에는 객체가 저장된 주소가 있으므로 객체가 console에 표시되어야한다. 따라서 "ONE"가 아닌 {name: "ONE"}형식이어야 한다.
다음으로 값이 다르게 나온이유는 one변수를 이용해서 객체를 새로만들고 재할당하였기 때문이다. 객체를 새로 만들면 힙에 새로운 저장공간이 만들어지고 해당주소가 바뀌게 된다. 
따라서 one에 할당되는 값은 기존의 let one = {name: "one"}을 선언하고 할당할때와는 다른 값(주소)이 할당되게 된다.
something에는 const something = one; 코드를 통해 기존의 one값을 할당받았다. 따라서 something은 바뀐 one과는 관계없이 기존의 {name: "one"}값을 가리키게 된다.
만약, one = {name: "ONE"}으로 재할당이 아닌 one.name = "ONE"; 으로 속성의 값 자체를 바꿨다면 결과는 예상 답으로 나왔을 것이다. 속성의 값을 바꾸는 행위는 재할당이 아니기 때문에 객체가 새로 만들어지지 않고 따라서 주소도 바뀌지 않는다.

 

Q3)

let one = 1;
const two = 2;

const something = one;

one = 101;

console.log(something); // ?

예상 답 : 1
예상 이유 : something에 할당되는 값은 primitive값인 1이다. 따라서 one이 재할당 되어도 값이 바뀌지 않는다.
정답 : 1

 

Q4)

let ken = {
  name: "ken",
  age: 30
};

const wan = {
  name: "wan",
  age: 35
};

const people = [ ken, wan ];

ken = {
  name: "KEN",
  age: 38
};

console.log(people);  // ?
console.log(ken === people[0]);  // ?

예상 답 : [ken, wan] false
예상 이유 : people은 배열의 요소로써 ken과 wan객체(주소)를 담았다. people을 console하면 배열을 보여주게 되는데 people에 담긴 ken객체는 재할당 된 ken이 아닌 기존의 ken값(주소)가 담겨있다. 따라서 기존의 객체를 출력한다.
people배열에 담긴 ken객체는 재할당되기 전의 ken객체이다. 따라서 새로할당 된 ken과 people배열에 담긴 ken은 서로 다른 주소값을 가지고있다. 따라서 false.
정답 : [{name: "ken", age: 30}, {name: "wan", age: 38}] false

 

Q5)

var secret = {
  data: "I am secret"
};

function destroy (stuff) {
  stuff = null;
}

destroy(secret);

console.log(secret); // ?

예상 답 : null
예상 이유 : secret은 처음에 객체가 할당되었다. 그러나 destroy함수를 거치면서 null값을 재할당받게 된다. 따라서 null출력.
정답 : {data: "I am secret"}


오답 이유 : secret은 reference자료형이다. destroy(secret);으로 함수를 호출하면 secert에 있는 객체의 주소를 파라미터로 넘게기 된다. 객체의 주소 자체는 primitive자료형이기 때문에 파라미터인 stuff도 primitive자료형이고 따라서 stuff = null;이라는 재할당은 이루어지지 않는다.
만약 stuff.data = "woaefjw";로 바꾼다면 객체의 주소에 있는 속성을 직접 바꾸는 것이므로 결과는 {data: "woaefjw"}로 나올 것이다.

 

** 메모리주소는 '포인터타입'이다. 포인터타입은 primitive 타입이다!

https://stackoverflow.com/questions/32926176/what-data-type-is-an-address

 

what data type is an Address?

I have a map that will store a string, and a corresponding address(memory) that contains a integer value or char value. map<string,address> myMap; //What datatype would address be? I'm not...

stackoverflow.com

https://www.javatpoint.com/primitive-vs-non-primitive-data-structure

 

Primitive vs non-primitive data structure - javatpoint

Primitive vs non-primitive data structure with Introduction, Asymptotic Analysis, Array, Pointer, Structure, Singly Linked List, Doubly Linked List, Graph, Tree, B Tree, B+ Tree, Avl Tree etc.

www.javatpoint.com

 

***primitive자료형은 함수에 파라미터(인자)로 전달될 때 해당 값이 복사되어 새로운 메모리 할당받아서 함수에 쓰인다. 즉, 파라미터는 원시타입의 변수와 값은 같지만 다른 주소를 가지므로 서로 영향을 미치지 않는다.
reference자료형은 함수에 파라미터로 전달될 때 객체(함수, 배열)가 있는 주소가 전달된다. 따라서 함수내에서 객체의 속성값을 바꾸면 원래의 값도 바뀌게 된다.

Call by reference, Call by value 문제이다!

https://kathak33.tistory.com/32 (매개변수, 지역변수, 전역변수)

 

var secret = {
    data: "I am secret"
  };
  
  function destroy (stuff) {
  console.log(secret);
  console.log(stuff);
  stuff.data = "I am stuff.data";
  console.log(secret);
  console.log(stuff);
    stuff= {
    data: "I am stuff"
  };
  console.log(secret);
  console.log(stuff);
  stuff.data = "I am stuff.data";
  console.log(secret);
  console.log(stuff);
  };
  
  destroy(secret);
  
  console.log(secret); // ?

 

위의 코드도 제대로 분석해보자..

 

* 매개변수도 지역변수 취급.
** destroy 함수 내에서 stuff를 선언해서 객체를 할당하였으므로 이제 stuff는 secret의 매개변수로서가 아닌 destroy함수 내에서의 지역변수로 동작.

'바닐라코딩 사전학습 > 코드연습, 퀴즈, 과제' 카테고리의 다른 글

Number Baseball  (0) 2021.12.28
JavaScript Koans-master  (0) 2021.12.28
Scope Quiz  (0) 2021.12.27
Craousel  (0) 2021.12.24
Background Changer  (0) 2021.12.24