FASTCAMPUS ST-FE 3기
Part 4. JavaScript Level up - Ch 1. JS 데이터 06~09
배열이나 객체를 해제하고, 그 값을 다른 변수에 담을 수 있게 하는 표현식.
변수명으로 값을 불러올 수 있어
객체에서 user.name || 배열에서 array[0] 식으로
번거롭게 참조하지 않아도되어 편리하다.
const user = {
name : 'oching',
age : 95,
email : 'oching.choi@gmail.com'
}
const {name, age, email, address} = user
console.log(name); //oching
console.log(age); //95
console.log(email); //oching.choi@gmail.com
console.log(address); //undefined
const {name, age, email, address} = user
변수선언을 한 뒤 원래 구조인 객체user와 연결. -> '구조분해할당해 변수로 사용하는군'
const {name:text, age, email, address} = user
만약 name이라는 변수명이 마음에 들지않는다면,,
name이라는 key값은 그대로 가져오되, name:바꾸고자하는변수명
으로 변경해 사용가능하다.
const fruits = ['apple', 'banana', 'cherry'];
const [a,b,c,d] = fruits;
console.log(a,b,c,d);
배열은 더 쉽다.
const [a,b,c,d] = fruits
원래 순서대로 똑같이 지정해주고
변수로 뽑아서 사용하면 끝!
근데 만약, 내가 'cherry'라는 값만 필요하다면?
const fruits = ['apple', 'banana', 'cherry'];
const [, ,b] = fruits;
console.log(b); //cherry
[, ,b]
위치로 값을 인식하기 때문에 ,로 순서 맞추는 것 유의하자.
배열데이터 안의 인자들을 나열시켜준다.
arr[i]식으로 부르지않아도 기호...
를 배열앞에 붙여주면
배열 속 값들을 불러 나열시켜준다.
const fruits = ['apple', 'banana', 'cherry']
console.log(fruits);
console.log(...fruits);
//console.log(apple', 'banana', 'cherry');
function toObject(a,b,c){
return {
a:a,
b:b,
c:c
}
}
console.log(toObject(...fruits)
console.log(...fruits);
전개연산자로 불러오지않았다면,
console.log(toObject(fruits[0], fruits[1], fruits[2])
로
각 배열의 인덱스로 접근해 인수를 전달해줘야했을 것이다.
배열안의 인자 개수와 파라미터의 개수가 다를때에도 전개연산자로
나머지 인수들을 모두 받아올 수 있게 할 수 있다.
const fruits = ['apple', 'banana', 'cherry', 'orange'] //배열속인자의 개수가 더 많음
console.log(fruits);
console.log(...fruits);
//console.log(apple', 'banana', 'cherry');
function toObject(a,b,...c){ //파라미터로 전개연산자처리, 여분의 값 다 받아온다.
return {
a:a,
b:b,
c:c
}
}
console.log(toObject(...fruits)
furits 배열에 있는 인자는 총 4개인데 toObject가 받는 파라미터는 a,b,c 세개로 존재했다.
때문에 마지막 orange는 전달받지못하는 상황이 발생한다.
이때 전개연산자를 활용하면 ...c에 남는 인자 모두 다 받아올 수 있다.
이를 reset parameter라고도 부른다.
💡 참고) js에서는 속성과 값의 이름이 같을 때 하나로 축약가능하다.
function toObject(a,b,...c){ return { a, b, c } }
원시데이터
string, number, boolean, undefined, null
참조형데이터
object, array, function
데이터간 비교시 일치, 불일치를 결정하는 기준은
어떠한 메모리 주소를 참조하는 지이다.
a === b의 결과가 true라면, a와b가 바라보고있는 메모리의 주소가 같다는 것을 의미한다.
원시데이터는
값을 할당해줄 때 새로운 메모리 주소를 생성하는 것이 아닌,
메모리 주소로 옮겨주는 것을 의미한다.
즉, let d = 4
일 때 d에게 새로운 메모리 주소를 생성시키는 것이 아니라,
4가 가지고있는 기존의 메모리 주소로 옮겨주는 것이다.
이를 두고 불변한다고 표현하는 것을 데이터 불변성이라고 한다.
하지만 참조형데이터
는 다르다. 참조형데이터의 경우
새로운 값을 할당 할 때 마다 새로운 메모리 주소를 갖는다.
즉 가변한다.
이 때 주의할 점은, 값을 할당시킨 경우 결국 메모리의 주소를 공유 시키는 것이기 때문에,
주소를 공유한 변수 간의 예기치 않은 동기화가 발생할 수 있어 조심해야한다.
let a = {k:1}
let b = {k:1}
console.log(a,b,a===b) //{k:1}, {k:1}, false - 각각의 메모리주소를 갖기때문
a.k = 7;
b = a ;
console.log(a,b,a===b) //{k:7}, {k:7}, true
a.k = 2;
console.log(a,b,a===b) //{k:2}, {k:2}, true
b=a
로서 b를 a가 가진 메모리 주소로 옮겨두었기때문에
이후 a.k의 값만 변경했다해도 같이 b.k 값 까지 변경된 것이다.
같은 메모리 주소를 공유하면 의도치 않은 값의 공유가 생길 수 있기에 복사해 새로운 객체를 만들면,
내용은 같지만 각자의 메모리 주소로 배정될 수 있지않을까?
때문에 사용되는 개념이 복사이다.
참조형 데이터들은 바로 대입연산자로 같은 메모리 주소를 공유시키지않고 복사해서 사용한다.
const user ={
name:'oching',
age : 95,
emails: 'oching.choi@gmail.com'
}
const copyUser = user;
console.log(copyUser === user); //true
user.age = 22;
console.log('user', user); //22
console.log('copyUer', copyUer); //22
const copyUser = user;
로 같은 메모리 주소로 할당 시키고 나니, user.age
값만 변경시켜도 copy.user
의 값까지 같이 공유되어 변경되었음을 알 수 있다.
const user ={
name:'oching',
age : 95,
emails: 'oching.choi@gmail.com'
}
const copyUser = Object.assing({}, user); //false
console.log(copyUser === user);
user.age = 22;
console.log('user', user); //22
console.log('copyUer', copyUer); //95
const copyUser = Object.assing({}, user);
로 복사해 새로운 객체를 만들고 나면,
복사해 생성된 객체는 다른 메모리 주소를 배정받기에
일치하지도 않고, 값의 동기화로 변경이 일어나지않는다.
const user ={
name:'oching',
age : 95,
emails: 'oching.choi@gmail.com'
}
const copyUser = (...user);
console.log(copyUser === user); //false
user.age = 22;
console.log('user', user); //22
console.log('copyUer', copyUer); //95
const copyUser = (...user)
로 값을 나열해 하나의 객체를 새로 생성해주며 복제했기에 false 값과 값의 변경 동기화가 일어나지않는다.
그럼 현재 user와 copyUser 두 객체 안의 내용은 복사가 되었을까? user.emails만 이메일 주소를 push해주었을 때 값의 동기화가 일어나지않기에 copyUser에는 push해준 이메일 주소가 없다. 이를 얕은 복사라고 한다.
user.emails.push('oching.choi@gamil.com');
console.log(user.emails === copyUser.emails); //false
console.log('user', user); //이메일주소가 value로 추가됨
console.log('copyUser', copyUser); //이메일주소 추가되지않았음.
참조데이터형 안에 또 다른 참조 데이터가 있을 경우 안의 key ,value값도 복사해와야하기에 깊은 복사를 고려해야한다.
lodash MDN사용
https://lodash.com/docs/4.17.15#cloneDeep
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
변수 deep에 clone을 하면서 안에 있는 key값과 그에 연결된 value 값 까지 꼼꼼히 복사해온 것을 알 수 있다.
값을 복사해왔지만 새로운 객체를 생성해온 것이므로 다른 메모리 값을 가지고, 때문에 일치를 확인하면 false로 확인된다.