2주차 금요일 수업에서는
목요일 수업 연장선으로 배열과 객체의 문법을 좀 더 알아보았고,
코드를 좀 더 간결하게 작성하는 방법인 단축평가와
JS에서 비동기 함수가 돌아가는 원리인 call stack에 대해서 배웠다.
추가 실습으로, 지난 실습때 적용했던 swiper 2개를
연동해보는 실습도 하였다.
이번 수업에서 얕은복사, 깊은복사 처음들어보았고
단축평가는 지레짐작으로 쓰고만 있었고
함수의 동작원리는 다른 언어에서 대충이나마 배운 기억이 있었지만
이번기회에 복습하면서
제대로 정리해보아야겠다는 생각이 들었다.!
학습내용
- 배열의 얕은복사(shallow copy) vs 깊은복사(deep copy)
- 배열과 객체에서의 구조분해할당
- 단축평가
- call stack과 비동기 동작원리
- swiper 2개 연동시키기
- 수업 때 질문들 Q&A
1. 배열의 얕은복사(shallow copy) vs 깊은복사(deep copy)
얕은 복사는 객체의 참조값(주소)를 복사하고,
깊은 복사는 객체의 값 자체를 복사한다.
(참고 블로그)
얕은 복사는 주소를 복사하는 것이므로
복사한 배열에서 값을 변경하면, 원래 배열에서도 값이 변하는 특징이 있다!
const original = [1, 2, 3];
const shallowCopy = [...original]; // 얕은 복사
console.log(shallowCopy); // [1,2,3]
이게 싫다면 값만 복사되는 깊은 복사를 사용하면 된다.
혹은 데이터 값 변경을 막고싶을때, 깊은 복사를 사용한다.
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
사실 지금까지 배열이나 객체의 복사를 자주 이용해본 적은 없는데,
알아두면 유용할 것 같다!
상황에 따라 적절하게 사용하면 될지싶다.
2. 배열과 객체에서의 구조분해할당
구조 분해 할당(Destructuring Assignment)은 배열이나 객체의 속성을 쉽게 추출하여
변수에 할당하는 문법이다.
즉, 배열의 알맹이(원소)만 쏙 ! 뽑아서
변수에 순서대로 적용하는 방식이다.
예시를 통해 이해해보자
🔍 배열의 구조분해할당
const array = [1, 2, 3];
// 배열에서의 기본적인 구조 분해 할당
const [a, b, c] = array;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
위 코드에서는 배열 array의 3개의 원소를
순서대로 a,b,c에 할당시킨다.
배열과 객체의 요소를 간단하고 명료하게 추출하여
변수에 손쉽게 할당할 수 있는 강력한 도구인 것이다!
🔍 객체의 구조분해할당
const obj = { x: 1, y: 2 };
// 기본적인 구조 분해 할당
const { x, y } = obj;
console.log(x); // 1
console.log(y); // 2
// 다른 변수 이름으로 할당
const { x: a, y: b } = obj;
console.log(a); // 1
console.log(b); // 2
위 코드에서는 객체 obj의 x,y값을
변수 x,y(객체 x,y와 다른거)에 각각 할당시킨다.
지금처럼 사용하고자 하는 변수(2번째 줄의 const {x,y})와
객체 내부에서의 이름(1번째 줄의 {x:1, y:2})이 같다면
기본적인 구조로 변수 이름으로만 적어도 된다!
(2번째줄 const {x, y})
구조분해할당을 언제쓸수 있을까? 생각해봤는데
api를 통해 json을 받아오고, 거기서 원하는 값만 추출하고싶을때
사용할 수 있을 것 같다!
const user = {
id: 42,
name: 'John Doe',
email: 'john.doe@example.com'
};
function greet({ name, email }) {
console.log(`Hello, ${name}! We have sent an email to ${email}.`);
}
greet(user);
// Output: Hello, John Doe! We have sent an email to john.doe@example.com.
user 객체를 api에서 받아왔다고 하면,
전달된 3개의 데이터 중에 name과 email만 쓰고싶으면
함수에서 인자를 받을 때 {name,email}로 변수 이름을 지정하여
넘어오는 값들중에 받고싶은 데이터를 따로 지정해줄 수 있다!
이것도 구조분해할당의 일종이다.
3. 단축평가
단축평가는 JS에서만 존재하는 것은 아니고, c++등 다른 여러 언어에서도 이미 널리 제공되는 기능이기도 하다.
코드를 쓰다보면, 여러상황을 고려하게 되므로
조건식을 쓸때 논리연산자(&&나 || 등)를 사용하는경우가 많다.
이때 JS에는 단축평가를 이용하여 비교대상자들에서 조건에 어긋나는 것이 있을경우
바로 종료해주는 '단축평가'라는 기능이 있다!
2가지의 변수를 && 연산자로 비교하는 경우를 살펴보자.
const a = false;
const b = 'Hello';
console.log(a && b); // false (b는 평가되지 않음)
const x = true;
const y = 'World';
console.log(x && y); // 'World' (y가 평가됨)
흐름은 이렇다.
2가지의 변수를 비교할 때
1. 앞의 피연산자가 true이면, 뒤 피연산자를 확인
2. 앞의 피연산자가 false이면, 바로 종료.(and 연산자 이므로)
실제로 코딩테스트 연습할때 여러번 사용해본 기능이기도 하고
코드를 간략하게 만들어주는데 은근 쓸모있는 기능인 것 같다!
🔍이때 확인해볼 점!
Q. ||(OR) 논리 연산자에서 2개의 피연산자가 모두 falsy할 때 뒤에 것을 무조건 반환하는 것 같은데
이 논리 연산자는 앞의 값이 참이든 거짓이든, 둘 다 거짓이든 무조건 뒤에 피연산자를 반환하는 건가요?
A. 자바스크립트에서 || 는 첫 번째 피연산자가 truthy 값이면 첫 번째 값을 반환하고,
그렇지 않으면(falsy) 두 번째 피연산자를 반환합니다.
4. call stack과 비동기 동작원리
다양한 API를 이용하고 받아오는 값을 처리하는과정에서
함수 call stack 개념과 비동기 개념의 이해는 매우 중요하다!
자바스크립트는 단일 스레드 기반이다.
즉 여러작업이 들어와도 동시에 하나의 작업만 처리가 가능하다.
이러한 싱글 스레드의 한계를 보완하기 위해, 비동기 콜백(asynchronous callback)이 사용된다.
비동기 콜백에는 Web APIs, Promise(ES6~)가 존재한다.
자바스크립트에서는 어떻게 이러한 비동기 콜백이 동작할까?
🔍자바스크립트 엔진 V8 구조
☑️ Memory Heap : 메모리 할당이 일어나는 공간
☑️ Call stack : 코드 실행에 따라 스택 프레임이 쌓이는 공간. 함수의 실행 순서를 결정한다.
LIFO(후입 선출)을 따른다.
🔍자바스크립트 런타임(동작 환경)
자바스크립트는 단일 스레드이지만,
자바스크립트 엔진이 돌아가는 환경, 즉 브라우저나 Node.js에서는
여러개의 스레드가 사용된다.(다중스레드)
- Web APIs : DOM, AJAX, Timer 등 브라우저에서 제공하는 api
- Callback queue : 콜백 함수들이 대기하는 곳(FIFO 선입선출)
- Event Loop : call stack이 비워질 때마다 callback queue에 대기 중인 콜백함수가 있다면, callback 함수를 call stack에 보내줌.
이렇게 다른 스레드 환경에서
자바스크립트 엔진과 구동 환경을 연동하기 위해 사용하는 장치가
Event Loop 이다!
🔍이벤트 루프(Event Loop)
싱글 스레드를 사용하면,
저번 수업시간 복습때 잠시 언급했듯이
함수 호출이 무한대로 쌓이는 콜백 지옥이 발생할 수 있다.
따라서, 자바스크립트에서 싱글 스레드의 한계를 보완하고자
비동기 콜백(asynchronous callback) 을 이용한다.
자바스크립트 코드 실행 중에 이벤트를 만나면
이벤트가 콜백 큐에 차례대로 쌓인다.
(콜백 큐는 FIFO, 선입선출 룰을 따른다.)
이벤트 루프는 콜 스택이 비었는지 정기적으로 확인하고,
비었으면 콜백 큐에 있는 이벤트를 가져다 콜 스택에 밀어넣는다.
이 한 번의 작업을 틱(tick) 이라고 한다.
이벤트 루프는 이 작업은 반복(loop)한다.
5. swiper 2개 연동시키기
swiper를 쓰다보면, 2개의 swiper가 동시에 동작하도록 하고 싶을때가 있다.
예를들어
사진 swiper / 사진 설명 swiper 각각 따로 작성했는데
둘이 동시에 동작하도록 만들고 싶은 경우이다.
방법은 의외로 간단하다!
2줄의 코드를 추가해주면 된다.
🔍swiper 2개를 서로 연결시키는 법
각각의 Swiper 객체들의 컨트롤러에 서로를 할당시켜주면 된다.
// Swiper 객체 생성(되어있어야 함)
var Swiper1 = new Swiper(".sec3TextSlide", {
...
});
var Swiper2 = new Swiper(".sec3TextSlide", {
...
});
// 서로 매칭
Swiper1.controller.control = Swiper2;
Swiper2.controller.control = Swiper1;
Swiper API에서 Controller의 Parameter로 'control'이 있는 것을 확인할 수 있고,
이를 활용해준 방법이다.
https://swiperjs.com/swiper-api#controller
Swiper - The Most Modern Mobile Touch Slider
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
swiperjs.com
역시! 모든 정답은 공식문서에 있구나! 하는 깨달음을 얻었다.
6. 수업때 Q&A
Q: (위에 이미 나온 질문)||(OR) 논리 연산자에서 2개의 피연산자가 모두 falsy할 때 뒤에 것을 무조건 반환하는 것 같은데, 이 논리 연산자는 앞의 값이 참이든 거짓이든, 둘 다 거짓이든 무조건 뒤에 피연산자를 반환하는 건가요?
A: 자바스크립트에서 || 는 첫 번째 피연산자가 truthy 값이면 첫 번째 값을 반환하고, 그렇지 않으면(falsy) 두 번째 피연산자를 반환합니다.
Q: h태그 안에 블록 태그 등 다른 거 넣으면 안되는건가요? 왜 안되나요?
A: 공식문서(mdn)을 보면 알 수 있습니다. h mdn에서 살펴보면, 가능한 컨텐츠: 구문컨텐츠(텍스트 레벨의 요소...) 라고 나와있습니다.
따라서 h 태그 안에 블록 태그를 넣는 것은 지양하는 것이 좋습니다.


복습후기
프로젝트할때는 구현에 급급하느라
기능을 제대로 이해하지 못한채 가져다 쓰는 경우가 많았는데,
이번 복습 기회에 자바스크립트의 중요한 개념을 이해할 수 있었다.
면접때 자바스크립트의 기본 개념과 함수 동작 개념들을
물어보는 걸로 알고있어서,
블로그 카테고리와 글로 따로 정리해보는 것도 좋을 것 같다!

'TIL(Today I Learn)' 카테고리의 다른 글
[데브코스 FE] 2주차 네번째 수업 2024/07/25 (1) | 2024.07.29 |
---|---|
[데브코스 FE] 2주차 세번째 수업 2024/07/24 (0) | 2024.07.27 |
[데브코스 FE] 2주차 두번째 수업 2024/07/23 (0) | 2024.07.26 |
[데브코스 FE] 2주차 첫번째 수업 2024/07/22 (2) | 2024.07.25 |
[데브코스 FE] 1주차 네번째 수업 2024/07/19 (3) | 2024.07.24 |