JS를 독학하면 놓치기 쉬운 부분들(1) - 기본편

김현우·2020년 10월 11일
0

JavaScript

목록 보기
1/8
post-thumbnail

자바스크립트는 객체로 시작해서 객체로 끝난다

JS에서는 기본 데이터 타입인 number, string, boolean, null, undefined를 제외한 모든 것들이 전부 '객체'이다. 배열은 물론이고 함수조차 사실은 객체로 표현되며, 당연히 메모리에도 객체의 형태로 올라간다.
number, string, boolean데이터타입은 객체가 아닌 하나의 값의 형태로 메모리에 올라가지만 객체처럼 다룰 수 있다. 이는 나중에 자세히 설명할 예정이다.


자바스크립트에서 객체는 '복사'가 아닌 '참조'된다

참조된다는 말은 맞지만, 이 아래의 내용에는 필자의 뇌내망상이 포함되어 있다🤷‍♀️

이해를 돕기 위해 다음의 코드를 먼저 보자

var apple = {color: 'red'}

위의 코드에서 사과의 정보를 담은 객체를 만들어서 apple이라는 변수에 할당했다. 이 과정에서 JS엔진은 apple 변수를 위한 메모리에 객체를 저장하지 않는다.
실제로는 객체를 먼저 생성해 메모리에 올리고, 그 주소를 apple변수에 할당한다. 마치 C언어의 포인터같다. 이후 apple객체를 사용할 때 내부적으로는 apple이 가리키는 주소에 있는 객체에 접근하는 것이다. 다시 말하지만, 변수에는 객체 자체가 할당되는 것이 아니라 객체가 올라간 메모리 주소가 할당된다.

var apple = {color: 'red'}
var apple2 = apple

appel2.color = 'yellow'

따라서 위의 코드를 실행하면 apple2의 color뿐만 아니라 apple의 color까지 yellow로 바뀐다.
var apple2 = apple
이라는 코드에서 apple2변수에 apple이라는 메모리 주소를 할당하기 때문에, 두 변수는 하나의 객체를 가리키고 있는 탓이다.

또한 함수의 매개변수로 객체를 넘길 때에도 객체의 값이 아닌 주소가 넘어간다.

이러한 특성 때문에 얕은 복사, 깊은 복사라는 개념이 나온 듯하다.


얕은 복사와 깊은 복사

위의 코드처럼 apple2에 apple을 할당하면 실제로 객체가 두 개가 된 것이 아닌, 한 객체를 가리키는 변수가 두 개가 된 것이다. 이러한 복사를 얕은 복사라고 하며, 메모리상에도 똑같은 객체를 새로 올려서 객체가 2개가 되는 복사(대부분의 사람들이 의도한 그 복사)깊은 복사라고 한다.

객체의 깊은 복사 방법

객체를 깊은 복사 하는 방법엔 여러 가지가 있다고 하지만 아직 필자는 한 가지만 쓰고 있다. 아래와 같이 apple객체를 깊은 복사한 apple2를 만들 수 있다.

var apple = {color: 'red'}
var apple2 = JSON.parse(JSON.stringify(apple))

JSON.stringify()메서드는 객체를 JSON형식의 문자열로 변환해주고,

JSON.parse()메서드는 JSON형식의 문자열을 뜯어서 새로운 객체를 만들어준다.

이러한 방식으로 만든 apple2는 color프로퍼티를 변경해도 apple객체에 영향을 주지 않는다.

배열의 깊은 복사 방법

우선 배열도 내부적으로는 일종의 객체이기 때문에 위와 같은 방법을 써서 복사할 수 있다.

그렇지만 그 방법은 거의 쓰이지 않고, 보통은 배열의 표준 메서드인 slice()를 이용한다.

Array.prototype.slice 메서드는 원본 배열의 원하는 부분을 칼로 자르듯 자른 새로운 배열을 반환한다. 매개변수로 시작점만 넘겨주거나 시작점과 끝지점을 넘겨줄 수도 있지만 아무것도 안 넘겨줄 수도 있다. 이런 경우 허공에 칼질을 한 새로운 배열을 반환한다. 즉, 그냥 똑같은 배열 하나 새로 만들어서 준다. 아래는 그 예시이다.

var fruits = ['apple', 'grape']
var fruits2 = fruits.slice()

0개의 댓글