프런트 개발 공부 중 비동기 통신에 대해 공부를 시작했다... 여기서부터 나의 고난이 시작되었다
비동기 통신의 개념과 사용법은 이해하였으나, 아직 문법적인 표현들이 익숙하지 않아서 그런지 볼 때마다 낯설다
더욱 익숙해지도록 다시 공부해보자!
JS가 실행되는 과정
JavaScript 엔진이 가동돼서 사람이 작성한 코드르 컴퓨터가 이해할 수 있도록 작업한다.
dynamic binding : this가 환경에 따라 바뀌는 것을 동적 바인딩이라 한다.
JavaScript를 이해하기 위해서 객체가 진정 무엇인지 이해하는 과정이 필요하다.
객체는 관련된 데이터와 함수의 집합이다. 변수를 선언하고 그 안에 여러 가지 값을 할당해주면 그것이 하나의 객체가 되는 것이다.
const person = {
name: ['Bob', 'Smith'],
age: 32,
gender: 'male',
interests: ['music', 'skiing'],
bio: function() {
alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
},
greeting: function() {
alert('Hi! I\\'m ' + this.name[0] + '.');
}
};
//person이라는 객체 생성!
//name, age, gender, interests와 같이 문자열,숫자,배열은 데이터 아이템인데 이것을 프로포티(속성)이라고 한다.
//함수는 메소드라고 한다.
위의 코드의 객체는 객체 리터럴(object literal)이라고 부른다. 리터럴 형식의 객체는 객체를 생성할 때 콘텐츠를 그대로 대입한다. 이것이 많이 쓰이는 상황은 주로 연속된 구조체나 연관된 데이터를 일정한 방법으로 변환하고자 할 때이다.(ex. 서버주소를 데이터베이스에 넣기)
객체의 표기법으로는 점 표기법과 괄호 표기법이 있다. 표기법은 쓰면서 익숙해지자.
괄호 표기법의 장점은 멤버의 값과 이름까지도 동적으로 변경하며 사용할 수 있다.
//점 표기법
person.age
person.name.first
//괄호 표기법
person['age']
person['name']['first']
이제 this의 개념이 나온다. this라는 것은 하나의 메서드인데, 이것은 지금 동작하고 있는 코드를 가지고 있는 객체를 가리킨다~~~라고 알려주는 메서드이다.
예를 들어, 같은 프로퍼티를 가지고 있는 두 객체가 있을 때, 함수를 작성하고 이름이 같은 프로퍼티를 this를 이용하여 작성하면, this는 실행 중인 코드가 속해있는 객체의 프로퍼티 값을 가져온다.
var person1 = {
name: 'Chris', // <- name변수 값 Chris
greeting: function() {
alert('Hi! I\\'m ' + this.name + '.');
}
}
//"Hi! I'm Chris." 를 출력
var person2 = {
name: 'Deepti', //<- name변수 값 Deepti
greeting: function() {
alert('Hi! I\\'m ' + this.name + '.');
}
}
//"Hi! I'm Deepti." 를 출력
실행 컨택스트 스택?
-코드의 흐름이나 함수 동작에 필요한 환경 정보가 담긴 객체를 의미
JavaScript의 Closure개념을 이해해 보자!
먼저 클로져를 이해하기 위해서는 자바스크립트의 언어적 범위지정 즉, Lexical scoping을 먼저 알아야 한다.
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() { // displayName() 은 내부 함수이며, 클로저다.
alert(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
init() 은 지역 변수 name과 함수 displayName()을 생성한다.
displayName()은 init() 안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있다. 여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다. 그런데 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다.
만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다. <mdn 클로저의 내용일부>
화살표 함수의 this는 호출된 함수를 둘러싼 실행 콘텍스트를 가리킨다. 따라서 화살표 함수의 this는 값이 바뀌지 않는다.
일반 함수의 this는 새롭게 생성된 실행 컨텍스트를 가리킨다.
rest operator? 나머지 매개변수 구문을 사용하면 함수가 정해지지 않은 수의 매개변수를 배열로 받을 수 있다.
function multiply(multiplier, ...theArgs) {
return theArgs.map(element => {
return multiplier * element //첫번째 이후의 모든 매개변수를 배열에 모은 후, 각각의 값을 첫번째 매개변수로 곱한 결과 반환
})
}
let arr = multiply(2, 15, 25, 42)
console.log(arr) // [30, 50, 84]
spread operator? 배열이나 객체를 전개할 때 사용!
const numbers = [1, 2, 3];
function getSum(...n) { // <- spread syntax
let sum = 0;
n.forEach((item) => {
sum += item;
});
return sum;
}
globalThis는 전역객체를 지칭하는 변수이다. 환경별 차이를 통일하여 하나의 변수로 서로 다른 전역 객체를 가리키게 한다.
콜백: 적절한 시점에 호출될 것으로 예상하여 다른 함수로 전달되는 함수. 콜백 중첩으로 인해 콜백지옥이 생김. 가독성도 떨어지고 오류 수정도 매우 어려워짐. 따라서 최신 API는 콜백을 사용하지 않고, 여기서 promise개념이 등장함.
자바스크립트의 비동기?
JS는 원래 동기 언어이다. 하지만 환경적으로 비동기 동작을 처리 할 수 있다. (setTimeout, Promise, Async-await 등등)
자바스크립트 엔진은 하나의 메인 스레드로 구성된다.
디바운싱 :
키워드 자동완성, 스크롤링, ajax 검색 등에 사용. 비용적인 문제와도 관련!
사용자가 키보드를 누를 때마다, 받아온 데이터를 출력해 준다고 할 때, 빠르게 입력하면 할수록 버벅거림이 생긴다. 따라서 함수가 호출되는 시점을 타이핑이 끝나는 시점으로 조정해 준다.
맨 마지막에 발생한 이벤트만을 가져옴
let alertTimer; // 타이머 선언
function alertWhenTypingStops() {
// 앞선 타이머를 리셋
clearTimeout(alertTimer);
const name = nameElem.value;
// 타이머 시작
alertTimer = setTimeout(() => alert(`입력된 이름: ${name}`), 1000);
}
const nameElem = document.querySelector("#inputName");
nameElem.addEventListener("input", alertWhenTypingStops);
쓰로틀링 :
이벤트가 한번 발생하면 일정 시간 동안은 발생하지 않도록 하는 것. 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것.
주로 스크롤을 올리거나 내릴 때 사용. 보통 성능 문제 때문에 많이 사용. 디바운싱과의 차이점은 설정한 특정 시간 주기로 계속 실행한다.
var timer;
document.querySelector('.body').addEventListener('scroll', function (e) {
if (!timer) {
timer = setTimeout(function() {
timer = null;
// 실행할 코드 내용
}, 200);
}
});
asyns/await :
promise를 활용한 비동기 코드를 간결하게 작성하는 문법.
asyns/await 문법으로 비동기 코드를 동기 코드처럼 간결하게 작성할 수 있다.
async 함수와 await 키워드를 이용한다.
await 키워드는 반드시 async함수 안에서만 사용해야 한다.
async로 선언된 함수는 반드시 promise를 리턴한다.
글로 정리하다 보니, Promise와 asyns/await에 대해서 자세히 다루지 못했다. 다음 글에 따로 빼서 정리해야겠다.