Javascript_30_14
안녕하세요!
Derek 입니다! 😛
인트로 뭐라고 적어야할지 생각이 안나요. 음 새해 복 많이 받으세요 정도?
이 새 친구 정말 귀엽네요. 두둠칫띠.
이번 게시물은 Day 14 project를 다루며 간단한 javascript
의 기본적인 원리(?)를 알아보려 합니다!
시작해볼게요 :)
14. JavaScript References VS Copying
목표
배열 및 객체에 대해서 깊은 복사, 얕은 복사에 대해서 학습한다.
오늘은 다소 딱딱한 이론적인 부분을 다룰 예정입니다. 전체적인 코드 제시보다는, 하나하나 주제에 맞게 설명하도록 할게요.
01. Reference
첫 주제는 참조
에 관한 내용입니다.
let age = 100;
let age2 = age;
console.log(age, age2); // 100, 100 출력
age = 200;
console.log(age, age2); // 200, 100 출력
let name = 'Wes';
let name2 = name;
console.log(name, name2); // "Wes", "Wes" 출력
name = 'wesley';
console.log(name, name2); // "wesley", "Wes" 출력
너무 간단하죠? 이건 그냥 넘어갈게요.
사실 아무 생각 없이 위에 코드를 보면 당연한데요, 아래 부분에서 약간 의아할 수 있습니다.
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
const team = players;
team[3] = 'Lux';
이렇게 한다면, team
배열은, (4) ["Wes", "Sarah", "Ryan", "Lux"]
이런식으로, 값이 바뀔겁니다.
하지만 문제는 원본배열인 players
에도 변화가 생깁니다.
즉, players
의 3번째 인자도 Lux
로 바뀐다는 뜻이에요.
그 이유는, 새로 생긴 team
이라는 변수는 단지 players
를 가르키는 포인터이기 때문에, 이런 일이 발생합니다.
새로운 배열을 생성하는 것이 아닌, 참조하는 포인터를 새로 생성한다.
라고 생각하면 될것 같아요.
02. Shallow copy - slice, concat, spread, Array
그렇다면 복사는 어떻게 하는 것일까요? 크게 4가지를 소개해보겠습니다.
1) slice
이는 배열을 복사하는 도구입니다.
const team2 = players.slice();
MDN
에 따르면,
slice(begin, end)
메서드는 어떤 배열의begin
부터end
까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
라고 합니다. begin
부터, end
- 1 까지 복사하여 새로운 배열을 반환합니다.
만약 아무런 인자가 포함되어 있지 않다면, 통째로 복사합니다. 즉, team2
에는 players
를 모두 복사하여 가지고 있겠죠!
2) concat
이는 배열, 문자열, 두 가지 타입에 대해서 사용할 수 있는 도구입니다.
MDN
에 따르면,
The
concat()
method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
기존 배열이나 문자열을 해치지 않고, 새로운 객체를 반환하죠. 여기에 자세히 나와있습니다.
const team3 = [].concat(players);
concat
함수는 항상 어떤 배열이나 문자열에 대해서 사용합니다. 즉, this
에 대해서 그 뒤로 붙이겠다는 거죠.
위의 예시처럼 빈 배열에 대해서 사용하면, 복사와 다름 없는 것을 확인할 수 있어요.
3) spread
spread
전개 구문은 ES6
부터 사용된 친구입니다.
MDN
에 따르면,
전개 구문을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있습니다.
라고 하는데, 이는 여기에 나와있는 여러가지 예시들을 보고 참고하는 것이 좋을 것 같아요.
const team4 = [...players];
team4[3] = 'heeee hawww';
console.log(team4); // players 배열에 "heee hawww" 가 추가됨.
새로운 배열에 players
배열 원소를 하나하나 뿌려준다는 느낌으로 이해하면 될 것 같습니다.
4) Array from()
간단하게 함수 하나로도 복사가 가능합니다.
const team5 = Array.from(players);
MDN
에 따르면, Array.from
의 정의는 다음과 같습니다.
The
Array.from()
static method creates a new, shallow-copied Array instance from an array-like or iterable object.
새로운 배열을 만드는 함수네요!
배열을 단순히 복사하기도 하지만, string
이나 Map
등에서도 다양하게 활용되는 것 같아요. 여기에 자세한 예시들이 있습니다 :)
03. Object Copies
이번에는 배열이 아니라 객체를 살펴보겠습니다.
const person = {
name: 'Wes Bos',
age: 80
};
const captain = person;
captain.number = 99;
console.log(captain); // {name: "Wes Bos", age: 80, number: 99}
console.log(person); // {name: "Wes Bos", age: 80, number: 99}
분명히 captain
에만 추가를 했는데, person
원본에도 number
속성이 99로 들어가있네요.
object
도 그냥 할당해버리면 참조되는 형식으로 설정되는 것을 확인할 수 있습니다. 그렇다면 위 4가지 방법처럼 새로운 객체를 반환하는 방법은 없을까요?
1) Object.assign()
Object.assign()
구문을 사용하면 됩니다.
const person = {
name: 'Wes Bos',
age: 80
};
const cap2 = Object.assign({}, person, { });
console.log(cap2); // {name: "Wes Bos", age: 80}
MDN
문법을 참고하면,
The
Object.assign()
method copies all enumerable own properties from one or more source objects to a target object. It returns the target object.
음.. 잘 와닿지는 않아요! target
에 source
을 붙이는 느낌인 것 같습니다 :)
Object.assign(target, ...sources)
즉, target
에 source
를 복사합니다.
const cap2 = Object.assign({}, person, { });
- 첫 번째 인자
{}
: 이 빈 객체에 집어넣을겁니다! - 두 번쨰 인자
person
:person
객체를 빈 객체(첫 번쨰 인자)에 넣을거에요! - 세 번쨰 인자
{ }
: 추가할 내용은 없습니다!
이런 방식이에요! 어렵진 않은것 같아요. 😊
그런데, 이 Object.assign()
친구도 shallow copy
입니다. 그 이유인 예시를 들어볼게요.
const wes = {
name: 'Wes',
age: 100,
social: {
twitter: '@wesbos',
facebook: 'wesbos.developer'
}
};
const dev = Object.assign({}, wes);
이렇게 하면, dev
에는 wes
객체가 복사되어 있습니다.
하지만, dev
의 social
인자를 건드려보면,
dev.social.twitter = "@Derek";
이 결과는 당연히 위 그림처럼 됩니다. 하지만! wes
객체도 변합니다.
이전에 참조처럼 바뀌던 현상이 또 일어난 것이 보이네요. 결국 더 깊숙한 정보는 바꾸지 못하는(?) 결과를 관찰 할 수 있었습니다.
이는 JSON
으로 해결이 가능해요.
const dev2 = JSON.parse(JSON.stringify(wes));
새로생성된 dev2
는 wes
객체를 통으로 문자열로 만드는 JSON.stringify
를 거쳐서 다시 객체화 시키는 JSON.parse
함수로 생성됩니다. 따라서 dev2
의 더 깊숙한 정보도 바꾸어도 본체는 바뀌지 않게 됩니다!
오늘은 기본적인 얉은 복사와 깊은 복사에 대해서 맛보기로! 여러가지 예시를 정리해보았습니다.
틀린내용이나 수정할 내용이 있다면 언제든지 피드백 부탁드립니다!
감사합니다!🤗
Author And Source
이 문제에 관하여(Javascript_30_14), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ghdtjrrl94/Javascript3014저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)