Post

[js] 동적인 이벤트를 다루는 자바스크립트의 호이스팅 및 개선된 문법

인터프리터 언어, JavaScript

🐀 웹페이지의 보조적 기능을 수행하기 위해 브라우저에서 동작하는 경량 프로그래밍 언어로 시작했다.
📕 인터프리터 언어란
런타임에 매번 한줄씩 바이트코드로 변환 후 실행하는 방식으로 동작한다.
따라서 실행파일을 생성하지 않고, 때문에 코드 실행속도가 느리다.
하지만, 코드를 한줄씩 실행하고 결과를 즉시 확인하는 인터랙티브한 실행으로
개발 및 디버깅 과정을 용이하게 만들어 준다.
⚠️ 또한, 많은 인터프리터 언어는 동적 타입 시스템을 사용한다(변수의 타입을 명시적으로 선언x)

즉, 브라우저 안에서 동작하는 프로그래밍 언어이다.
사용자와의 상호작용 동적인 콘텐츠 생성데이터 처리의 기능을 수행하기 위해 만들어졌다.
마우스 클릭 및 이동, 키보드 입력 등의
* 이벤트에 대한 반응을 처리할 수 있으며,
* 동적으로 요소를 추가하거나 변경할 수 있다.
* 사용자의 입력을 검증하거나
* 서버와 통신하여 데이터를 가져오거나 전송할 수 있다.

DOM과 이벤트리스너

🐁 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

🐁 ECMAScript6부터 범용프로그래밍 언어로써 필요한 기능을 대거 도입했다

🍍크로스 브라우징(Cross Browsing) 이슈란
브라우저에 따라 웹페이지가 정상적으로 동작하지 않는 현상을 말한다.

모든 브라우저에서 정상적으로 동작하는 표준화된 자바스크립트인 ECMAScript6부터
let/const 키워드 화살표함수 클래스 모듈 같은 범용프로그래밍 언어에 필요한 기능를 도입했다.
⚠️ ECMA : 컴퓨터 시스템 표준을 관리하는 기구

더불어, 브라우저 외부에서도 자바스크립트를 실행할 수 있도록, V8 자바스크립트 엔진🚂을 구동시키는 런타임 환경인 Node.js를 통해 브라우저에서 독립시켜
백엔드까지 다룰 수 있게 되었다.

📕 싱글 스레드 이벤트 루프 기반, Node.js
사용자의 입력 타이머 네트워크 요청과 같은 이벤트를 계속 감지하는 이벤트 루프
이벤트 큐에 이벤트를 순차적으로 추가하고 처리한다.
각 이벤트에 대응하는 콜백함수 or 핸들러를 실행하여 싱글스레드 환경에서
비동기 작업을 처리하는 매커니즘을 말한다.
⚠️ 싱글 스레드 환경이어서 동시성 문제를 피할 수 있다.

문서가 로드되기 전, 호이스팅

🐁 호이스팅이란 문서가 로드되기 전에 선언된 변수/함수를 미리 메모리에 올리는 과정을 말한다

변수 및 함수 선언이 해당 스코프의 최상단으로 옮겨지는 현상호이스팅이라 한다.
선언부만 끌어올려지고 값을 할당하는 부분은 그대로 남아있다.

1
2
3
console.log(x); // undefined
var x = 5;
console.log(x); // 5

해당 코드의 유효범위, 스코프

🐙 블록레벨 스코프 vs 함수레벨 스코프
  • 함수레벨 스코프
    변수나 상수가 함수 내에서 선언될 때, 해당 함수 내에서만 유효한 스코프를 말한다.
    때문에 모든 함수에서 접근 가능한 전역변수가 많아질 수 있다.
    var 키워드함수레벨 스코프를 지역스코프로 인정하고, 중복 선언이 가능해 자칫 의도치 않은 결과를 초래할 수 있다.
  • 블록레벨 스코프
    변수나 상수가 블록{}내에서 선언될 때, 해당 블록 내부에서만 유효한 스코프를 말한다.
    let / const 키워드는 블록레벨 스코프를 지역스코프로 인정하고 변수의 범위가 좁아지면서
    의도치 않게 변수가 수정되는 것을 방지한다.
    변수가 더 짧은 생명주기를 가져 메모리 누수 가능성이 줄어든다.
    또한, 변수 호이스팅이 발생하지 않는 것처럼 동작해 코드의 흐름을 저해하지 않는다.
    • let 키워드
      값의 재할당이 필요한 경우 권장
    • const 키워드 대문자 스네이크케이스
      상수를 표현하는 경우 권장
      값의 재할당이 금지되어 있어 한번 정해진 변수값을 변경할 수 없다.
      ⚠️ const 키워드로 할당한 변수에 객체를 할당한 경우, 그 값을 변경할 수 있다.

리터럴과 표현식

🐙 리터럴이란 미리 약속한 값 생성 표기법을 말한다

JavaScript의 원시타입에는 숫자 문자열 불리언 undefined null 심벌 타입이 있다.

🍍 null의 의미
(1) 아직 알려지지 않은 값이다.
(2) 이전에 참조하던 값을 더이상 참조하지 않겠다.

객체(Object) 배열(Array) 함수(Function) 등을 참조타입이라 한다.

각 타입에 대응되는 리터럴이 있다.
예를 들어, 객체 리터럴은 { name: 'lee', age: 30 } 형태를 가지고,
배열 리터럴은 [1, 2, 3] 형태를, 함수 리터럴은 function() { } 형태를 가진다.

📕 향상된 객체 리터럴 (Enhanced Object Literal)
(1) 키와 값이 같은경우, 축약
(2) 속성에 함수를 정의할 때, function 키워드 생략가능
1
2
3
4
5
6
let josh {
  a, 
  coding() {
    console.log("코딩");
  }
}
📘 자주 사용되는 배열 내장 API
기본적으로 인덱스를 통해 배열에 값을 넣고 빼는 것은 위험하다.
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
    };
    
This post is licensed under CC BY 4.0 by the author.