[js] 동적인 이벤트를 다루는 자바스크립트의 호이스팅 및 개선된 문법
인터프리터 언어, JavaScript
런타임에 매번 한줄씩 바이트코드로 변환 후 실행하는 방식으로 동작한다.
따라서 실행파일을 생성하지 않고, 때문에 코드 실행속도가 느리다.
하지만, 코드를 한줄씩 실행하고 결과를 즉시 확인하는 인터랙티브한 실행으로
개발 및 디버깅 과정을 용이하게 만들어 준다.
⚠️ 또한, 많은 인터프리터 언어는 동적 타입 시스템을 사용한다(변수의 타입을 명시적으로 선언x)
즉, 브라우저 안에서 동작하는 프로그래밍 언어이다.
사용자와의 상호작용 동적인 콘텐츠 생성 및 데이터 처리의 기능을 수행하기 위해 만들어졌다.
마우스 클릭 및 이동, 키보드 입력 등의
* 이벤트에 대한 반응을 처리할 수 있으며,
* 동적으로 요소를 추가하거나 변경할 수 있다.
* 사용자의 입력을 검증하거나
* 서버와 통신하여 데이터를 가져오거나 전송할 수 있다.
DOM과 이벤트리스너
웹페이지가 로드될 때, 브라우저가 생성하는 element 기반 tree형태의 문서 객체 모델을 DOM(Document Object Model)
이라 한다.
JavaScript는 DOM을 기준으로 element(요소)를 찾아서 재구성(추가, 속성추가, 제거)할 수 있다.
html에서의 element들은 JavaScript에서는 객체로 다루어진다.
element들은 JavaScript에서 Node라 불린다.
🚀 DOM의 element 찾기
1
2
3
4
5
6
document.getElementById("customId"); // Node
document.getElementByClassName("customClass"); // NodeList
document.getElementByTagName("div"); // NodeList
document.querySelector("h2"); // Node
document.querySelectorAll("h2"); // NodeList
🚀 이벤트리스너 등록
- 이벤트가 발생할 때, 특정 함수를 호출한다.
1
2
3
document.querySelector("h2").addEventListener("moseover", function () {
this.style.border = "1px solid red";
});
- 포커스 이벤트 focus blur
- 폼 이벤트 submit reset
- 뷰 이벤트 scroll resize
- 키보드 이벤트 keydown keyup
- 마우스 이벤트 mouseover mouseout mousemove click dbclick
- 드래그 앤 드롭 이벤트 dragstart drag drop
브라우저가 본래 내장하고 있는 객체를 BOM(Browser Object Model)
이라 한다.
BOM에는 window document location history screen navigator 등이 있는데,
window는 JavaScript의 최고 조상이다. (생략0)
1
2
3
4
5
6
<script type="text/javascript">
onload = function () {
// window. 생략
alert("문서가 모두 load 되었습니다.");
};
</script>
보통 window.onload
를 통해 DOM이 모두 로드 된 뒤에 함수를 호출하는 방식으로 쓰인다.
크로스 브라우징 이슈와 표준화된 ECMAScript6
🍍크로스 브라우징(Cross Browsing) 이슈란
브라우저에 따라 웹페이지가 정상적으로 동작하지 않는 현상을 말한다.
모든 브라우저에서 정상적으로 동작하는 표준화된 자바스크립트인 ECMAScript6부터
let/const 키워드 화살표함수 클래스 모듈 같은 범용프로그래밍 언어에 필요한 기능를 도입했다.
⚠️ ECMA : 컴퓨터 시스템 표준을 관리하는 기구
더불어, 브라우저 외부에서도 자바스크립트를 실행할 수 있도록, V8 자바스크립트 엔진🚂
을 구동시키는 런타임 환경인 Node.js를 통해 브라우저에서 독립시켜
백엔드까지 다룰 수 있게 되었다.
사용자의 입력 타이머 네트워크 요청과 같은 이벤트를 계속 감지하는 이벤트 루프는
이벤트 큐에 이벤트를 순차적으로 추가하고 처리한다.
각 이벤트에 대응하는 콜백함수 or 핸들러를 실행하여 싱글스레드 환경에서
비동기 작업을 처리하는 매커니즘을 말한다.
⚠️ 싱글 스레드 환경이어서 동시성 문제를 피할 수 있다.
문서가 로드되기 전, 호이스팅
변수 및 함수 선언이 해당 스코프의 최상단으로 옮겨지는 현상을 호이스팅이라 한다.
선언부만 끌어올려지고 값을 할당하는 부분은 그대로 남아있다.
1
2
3
console.log(x); // undefined
var x = 5;
console.log(x); // 5
해당 코드의 유효범위, 스코프
- 함수레벨 스코프
- 변수나 상수가 함수 내에서 선언될 때, 해당 함수 내에서만 유효한 스코프를 말한다.
- 때문에 모든 함수에서 접근 가능한 전역변수가 많아질 수 있다.
- var 키워드는 함수레벨 스코프를 지역스코프로 인정하고, 중복 선언이 가능해 자칫 의도치 않은 결과를 초래할 수 있다.
- 때문에 모든 함수에서 접근 가능한 전역변수가 많아질 수 있다.
- 블록레벨 스코프
- 변수나 상수가 블록
{}
내에서 선언될 때, 해당 블록 내부에서만 유효한 스코프를 말한다.- let / const 키워드는 블록레벨 스코프를 지역스코프로 인정하고 변수의 범위가 좁아지면서
- 의도치 않게 변수가 수정되는 것을 방지한다.
- 변수가 더 짧은 생명주기를 가져 메모리 누수 가능성이 줄어든다.
- 또한, 변수 호이스팅이 발생하지 않는 것처럼 동작해 코드의 흐름을 저해하지 않는다.
- let / const 키워드는 블록레벨 스코프를 지역스코프로 인정하고 변수의 범위가 좁아지면서
- let 키워드
- 값의 재할당이 필요한 경우 권장
- const 키워드 대문자 스네이크케이스
- 상수를 표현하는 경우 권장
- 값의 재할당이 금지되어 있어 한번 정해진 변수값을 변경할 수 없다.
- ⚠️ const 키워드로 할당한 변수에 객체를 할당한 경우, 그 값을 변경할 수 있다.
- 값의 재할당이 금지되어 있어 한번 정해진 변수값을 변경할 수 없다.
리터럴과 표현식
JavaScript의 원시타입에는 숫자
문자열
불리언
undefined
null
심벌
타입이 있다.
🍍 null의 의미
(1) 아직 알려지지 않은 값이다.
(2) 이전에 참조하던 값을 더이상 참조하지 않겠다.
객체(Object) 배열(Array) 함수(Function) 등을 참조타입이라 한다.
각 타입에 대응되는 리터럴이 있다.
예를 들어, 객체 리터럴은 { name: 'lee', age: 30 }
형태를 가지고,
배열 리터럴은 [1, 2, 3]
형태를, 함수 리터럴은 function() { }
형태를 가진다.
(1) 키와 값이 같은경우, 축약
(2) 속성에 함수를 정의할 때, function 키워드 생략가능
1
2
3
4
5
6
let josh {
a,
coding() {
console.log("코딩");
}
}
기본적으로 인덱스를 통해 배열에 값을 넣고 빼는 것은 위험하다.
arr.push(10);
arr.pop();
arr.slice() : 특정 인덱스에 있는 값을 반환 (기존 배열이 변경되지 않음, 부수효과x)
arr.splice() : 특정 인덱스에 있는 값을 변경 (기존 배열이 변경됨, 부수효과 ㅇ)
arr.length : 배열의 길이 반환
foreach : 배열의 반복을 위한 내장 api
each : jquery에서 제공하는 반복문이다.
※ each는 foreach와는 다르게 break와 continue같은 제어문을 사용할 수 없다. 대신 return false를 사용..
- 🍪 배열의 반복문: map, filter, foreach
- map이나 filter의 동작을 모두 foreach로 구현할 수 있지만
- foreach를 쓰는 것보다 map과 filter를 쓰는 것을 권장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const arr = ["a", "b", "c"];
const newArr = [];
// map
arr.map(function (item) {
return item * 10;
});
arr.foreach(function (item) {
newArr.push(item * 10);
});
// filter
arr.filter(function (item) {
// true인 요소만 반환
if (item == 10) {
return true;
}
});
arr.foreach(function (item) {
if (item == 10) {
newArr.push(10);
}
});
// ⚠️ foreach vs each
리터럴처럼 값으로 평가되는 문(최소실행단위)을 표현식이라 하며, 값처럼 사용가능하다.
표현식으로 평가되는 문에는 리터럴뿐만 아니라, 식별자 참조 연산식 함수호출 조건식 이 있다.
개선된 문법 (ECMASCRIPT6)
- 템플릿 리터럴
Template Literal
- 자바스크립트에서 문자열을 선언하는 최신 방식이다.
자바스크립트의 변수를 문자열 안에 끼워넣을 수 있다.${}
1 2
let a = "hi"; let message = `${a} js!!`;
- 템플릿 리터럴
- 구조분해 문법
Destructuring
- 배열의 요소를 쉽게 꺼내와 여러개를 한번에 각각의 변수에 할당할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12
// 배열 const arr = ["apple", 10]; const [myFruit, myNum] = arr; // 객체 const josh = { skill: "js", age: 21 }; const { skill, age } = josh; const { skill: mySkill, age: myAge } = josh; // 할당할 변수의 이름을 지정해줄 수도 있다.
- 구조분해 문법
- 스프레드 오퍼레이터
Spread Operator
- 값을 복사하여, 이동시킬 때 많이 사용된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 배열 const arr = ["a", "b"]; const newArr = [...arr, "c"]; // 객체 const obj = { a: 10, b: 20 }; const obj2 = { ...obj, c: 30 };
- 스프레드 오퍼레이터