-
자바스크립트 참조타입데이터(reference type data)javascript 2020. 11. 6. 08:07
자바스크립트 참조타입데이터(reference type data)
- premitive type data : string, number, boolean, undefined, null
- reference type data : array, object, function
원시타입 데이터(Primitive type data)는 변수에 직접 데이터 값을 넣어준다. 각 변수간에 원시타입 데이터를 복사할 경우에 데이터 값이 복사되기 때문에 기존의 데이터에 영향이 가지 않는다.
let data1 = 1; //data1 = 1 let data2 = data1; //data2 = 1 //data2라는 변수에 data1의 값을 복사해 넣어주었다. data2 = 2; //data2 = 2 data1 //1 data2 //2 //data1의 값에는 아무런 영향이 가지 않는다.
그렇지만 참조타입 데이터(reference type data)는 주소를 복사한다. 그렇기 때문에 복사한 데이터에서 원소를 변경하게 된다면 주소안의 데이터가 변경되는 것이기 때문에 기존의 데이터에도 영향이 가게된다.
자바스크립트에서 원시 자료형이 아닌 모든 것은 Object이다. 배열([])과 객체({}), 함수(function(){})가 대표적이다.
이런 자료형을 참조자료형(reference data type)이라고 부른다.
참조 자료형이 변수에 할당되는 경우는, 변수에 이 데이터가 저장되는 곳의 주소가 할당이 된다.원시 자료형은 배열과 객체와는 다르게 하나의 정보만 담고 있기 때문에 변수에 직접 값을 복사해도 큰 문제가 없다. 변수 하나에 값 하나가 들어간다고 단순하게 이해할 수 있다.
참조자료형은 조금 다르다. 어떻게 코드를 작성하느냐에 따라서 담길 수 있는 정보의 크기가 천차만별이다. 그렇기 때문에 동적(dynami)으로 변수의 크기가 변할 수 있어야 한다.
원시자료형의 경우 stack에 직접적인 변수의 값이 들어간다.참조자료형의 경우, 메모리에 공간에 데이터를 저장하고, 변수에는 그 공간의 주소만 참조하도록 한다. stack에는 heap의 주소가 들어가게 되고 heap에 데이터가 들어간다.
let a = {fruit : 'banana'}; let b = a; a //{fruit : 'banana'} b //{fruit : 'banana'} b.fruit = 'apple'; a //{fruit : 'apple'} b //{fruit : 'apple'}
let b = a; 변수 a를 변수 b에 할당하는 경우, 변수 a의 값은 참조 자료형이기 때문에 a의 값 {fruit : 'banana'}의 주소를 b에 할당한다. 값 자체를 할당하는 원지자료형과의 차이점이다.
이 상태는 변수 a와 b 모두 같은 {fruit : 'apple'}이라는 객체의 주소를 바라보고 있다.
b.fruit = 'apple'
값이 'banana'였던 b.fruit에 'apple'을 할당했다. 그렇다면 a.fruit는 어떻게 될까? 같은 주소를 바라보고 있는 b.fruit가 'apple'로 변경되었으니, 같은 곳을 바라보고 있었던 a.fruit도 2가 된다.console.log('korea' === 'korea'); //true console.log(9.2 === 9.2); //true console.log([1,2,3] === [1,2,3]) //false console.log({fruit : 'melon'} === {fruit : 'melon'}) //false
참조 자료형의 ===(strict equality)는 주소값이 같은지를 확인한다. 그렇기 때문에 두 참조 자료형의 주소값은 다르다고 판단을 내릴 수 있다.
console.log([1,2,3] === [1,2,3]);
컴퓨터가 이 코드를 읽으면서, 이미 두 개의 heap 저장 공간의 주소를 확보했다. 다만 우리는 눈으로 확인하지 못할 뿐이다. 배열([])과 객체({})등 참조 자료형을 읽을 때, 미리 주소값과 메모리 값을 잡아둔다고 생각하면 된다. 그러므로[] === []
도 true가 나오지 않는 다.코드가 실행된 후,
player.score
의 값은 무엇일까?let player = {score : 5} function doSomething(obj){ obj.score = 2; } doSomething(player);
답은 2이다.
doSomething(player);
에서 함수doSomething
에 변수player
를 인자로 전달하여 호출한다.function doSomething(obj){ obj.score = 2; }
함수가 호출되면 매개변수 obj에 변수 player의 값이 할당된다. 즉 {score : 5}의 주소값이 할당된다. obj.score에 2를 할당하면, obj와 player는 같은 주소값을 가지고 있기 때문에, player.score도 2가 되게 된다.const변수에 대해
Const
- 'const'로 선언된 변수에는 재할당(reassignment)이 금지된다.
const a; //Uncaught SyntaxError: Missing initializer in const declaration. const로 변수를 선언할 때는 처음부터 초기화를 해주어야 한다. const b = 1; const b = 1; //Uncaught SyntaxError: Identifier 'b' has already been declared. 재선언은 당연히 안된다. const num = 0; //이런식으로 const로 변수를 선언하고 할당해주면, num = 0; //이렇게 기존의 값과 동일한 값을 다시 할당해 준다고 해도 에러가 발생한다.
- 'const'로 선언된 배열의 경우 새로운 요소를 추가하거나 삭제할 수 있다.
const arr = []; arr.push(3); arr.push('kiki'); arr //[3, 'kiki'] //여전히 재할당은 금지된다. arr = [1,2,3] //Uncaught TypeError: Assignment to constant variable.
- 'const'로 선언된 객체의 경우, 속성을 추가하거나 삭제할 수 있다.
const obj = { x : 1}; obj.x // 1 //삭제 delete obj.x; obj.x //undefined //새로운 속성 추가 obj.occupation = 'SW Engineer'; obj['name'] = 'Jaehyeon'; obj["occupation"] //"SW Engineer" obj.name //"Jaehyeon" //여전히 재할당은 금지된다. obj = {x : 123} //Uncaught TypeError: Assignment to constant variable.
const person = { son : { age : 9, }, }; const boy = person.son; boy.age = 20; //1.person.son.age = ? //2.person.son === boy ? //3.person.son = ? /** 정답******* * 1. 20 //person.son = {age : 9}라는 객체이고, boy에 person.son의 주소값을 할당하였다. 즉, 현재 boy에는 {age :9}의 주소값이 할당되어 있는 것이다. 그리고 boy.age = 20으로 실제 데이터를 바꿔주었으니 같은 주소를 바라보고 있는 person.son.age의 값도 20이 된다. * 2. true //const boy = person.son; 이 코드에서 person.son의 주소값을 boy에 할당해 주었기 때문에 같다고 볼 수 있다. * 3. {age : 20} //1번과 비슷한 이유 */
'javascript' 카테고리의 다른 글
script태그의 위치 (0) 2020.11.12 SpreadSyntax(전개문법), RestParameter (0) 2020.11.10 문자열 (0) 2020.10.28 Function Statements(Declarations) and Expressions (0) 2020.10.10 forEach에 대해서 참조한 블로그 + 여러가지 배열 메소드 (0) 2020.06.06