[JS] 동기 비동기, 스프레드 연산자, 깊은복사 얕은복사, rest parameter




promise약속

프로미스는 비동기로적으로 동작을 시켜주어야 함.

서버에 요청을 보내면 실제 서버와의 통신시간의 격차때문에 자바스크립트가 실행되는것보다 빨리 실행되기는 어렵다.

fetch요청에 아직 들어오지 않아서 기다리고 있는데 자바스크립트는 이미 실행되서 기다리고 있는 중 인경우,

서버에서 ‘언젠가는 받을 예정인데 아직은 응답을 받지 못했다’는 상태로 약속되어있는것을 promise라고 한다


프로미스의 3가지 상태

  • fulfilled : 요청이 성공한 상태
  • pending : 요청에 대한 응답을 기다리고 있는 상태
  • rejected : 요청이 실패한경우
const promiseTest = function(){
	return new Promise((resolver, reject) => {
		setTimeout(() => {
			resolver(100);	//promise상태가 fulfilled가 됨. 요청에 성공했을때는 resolver에 담아주면 됨
		},2000);
	});
};

promiseTest().then((res) => {
  console.log(res);
});	//pending상태인 데이터를 기다려줌

promiseTest().then() : 프로미스객체를 return해주는 함수 promiseTest다음에 then()을 붙여주면

프로미스가 pending에서 fulfilled가 될때까지 기다린다. fulfilled가 되면 그때 then을 실행한다. 그때 함수를 실행시킬 수 있다




구조분해할당

구조화 되어있는 배열, 객체와 같은 데이터를 destructuring 시켜, 각각의 변수에 담는것

let arr = [1,2]
let [one,two] = arr;


구조분해할당은 iterable만 가능한데,

배열은 iterable하지만, 객체는 순회를 할 수 없다.

그렇기 때문에 객체는 구조분해할당을 해주려면 에러가 뜨는데..

그렇담 객체는 구조분해할당을 할 수 없는건가!? 하면 가능하다.

let obj = {nane : 'other', gender: 'male'};
let {name, gender} = obj;

실제 객체에 존재하고 있는 key값을 적어주어야 한다. 안그러면 제대로 구조분해할당이 되지 않는다.

아 물론 원하는 이름으로 바꿔서 할당해줄 수도 있다.

그럴때는 아래처럼 적어주면 됨

let {name:newName, gender: newGender } = obj;

newName을 새로운 name명으로, newGender를 새로운 gender명으로 구조분해할당해준것




spread 연산자 = ...

배열이 한꺼풀 벗겨지면서 값을 보여준다

let arr = [1,2,3,4,5];

console.log(arr);		//[1,2,3,4,5]
console.log(...arr);	//1,2,3,4,5


let str = 'hello';
console.log(str);		//'hello'
console.log(...str) 	//'h''e''l''l''o'

참조타입의 데이터 복사방법(얕은 복사, 깊은 복사)

얕은복사 : 주소값까지만 복사

깊은복사 : 실제 데이터까지 복사

obj = {name: 'otter', gender: 'male'};

const newObj = obj;
console.log(newObj);	//{name:'otter', gender: 'male'}

//얕은복사로 원본을 복사하면 복사본을 변경해도 원본이 변경된다. 
newObj.name = 'rabbit';
console.log(newObj);	//{name:'rabbit', gender: 'male'}
console.log(obj)		//{name:'rabbit', gender: 'male'}

const copyObj = {...obj};	//새로운 객체로 만들어짐
copyObj.gender = 'female';
console.log(copyObj);		//{name:'rabbit', gender: 'female'}

let origin = {
  	name: 'otter',
  	age: 25
}
//그래서 데이터값을 변경하려면 아래처럼 값을 받아와야함
let copy = {
  	name : origin.name,
	  age : origin.age
}
//위처럼 복사하면 번거로우니까 스프레드 연산자 쓰자
let copy = {...origin}


//배열도 가능
let arr = [1,2,3,4,5];
let secArr = [6,7,8];

let copy = [...arr, ...secArr]
console.log(copy);	//[1,2,3,4,5,6,7,8]



그런데, 원본객체안에 또다른 객체가 들어있을 경우 스프레드 연산자를 사용하더라도 제대로 복사가 되지 않는다. (주소값까지만 복사해왔기 때문)

let origin = {
	name : 'otter',
	age : 25,
	favoriteFood : {
		first : 'sushi',
		second : 'hamburger'
	}
}

const copy = {...origin}
copy.favoriteFood.first = 'cold noodle';
console.log(oriign.favoriteFood);	//{first:'cold noddle', second:'hamburger'};

그렇다면, 제대로 복사하기 위해서는 어떻게 해야할까?

바로 깊은복사를 사용하면 된다

let origin = {
	name : 'otter',
	age : 25,
	favoriteFood : {
		first : 'sushi',
		second : 'hamburger'
	}
}

const copy = JSON.stringify(copy);
console.log(copy);	////{name : 'otter',age:25,favoriteFood :{first : 'sushi',second : 'hamburger'}}

const deepCopy = JSON.parse(copy);
console.log(deepCopy);	//{name : 'otter',age:25,favoriteFood :{first : 'sushi',second : 'hamburger'}}

const copy = JSON.stringify(copy); => 객체를 문자열로 변경하게 되면 객체의 주소값은 사라지게 됨.

const deepCopy = JSON.parse(copy); => 문자열이 된 객체를 새로운 주소값을 가진 객체로 생성해냄(완전히 새로운 객체를 생성)




Rest Parameter

let origin = {
	name : 'sora',
	age : 31,
	petName: 'sera',
	hobby : 'playing drums'
}

만약 위 객체에서 필수값만 받아온뒤(petname과 hobby는 삭제) 새로운 객체값을 만들어주고싶다면?

아래처럼 작성하면 됨.

const essentialData = {
	name : origin.name,
	age : origin.age
}

but, 이럴때 rest parameter를 사용할 수 있다

const {petName, hobby, ...rest} = origin

petName에는 sera라는 문자열이 담여있을거고,

hobby에는 playing drums라는 문자열이 담겨있을거다.

…rest는 {name : 'sora', age: 31}

어떤 객체에서 필요없는 데이터를 걸러줄때 rest parameter를 사용한다.

혹은 어떤 데이터만 걸러서 쓰고싶을떄 사용한다.



rest 대신에 아무 변수명을 써도 된다.

const {petName, hobby, ...원하는변수명} = origin
















© 2018. by sora

Powered by sora