직무부트캠프 프론트 2주차 과제
프론트 기본 개념
HTML의 form과 action의 개념
form 은 사용자로부터 정보를 수집하기 위해 사용하는 요소이며,
method 속성은 폼 데이터를 어떻게 전송할지를 지정한다.
폼 데이터는 action 속성(폼 데이터가 제출될 URL을 지정하는 속성)에 지정된 페이지로 전송됩니다.
<form action="/action_page.php" method="get">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
</form>
기본 from 메서드 구조 ▲
- method (전송 방식)
- GET / POST (폼에서 데이터가 전송되는 주요 방식)
GET
- 폼 데이터를 URL에 name/value 쌍으로 추가
- GET 메서드는 폼 데이터를 URL에 쿼리 스트링으로 추가한다. 예를 들어, 사용자가 "username" 필드에 "john"을 입력하면, URL이 다음과 같이 변경된다 : example.com/page?username=john.
- 특징:
- 데이터가 URL에 표시되어서 사용자가 쉽게 확인할 수 있다.
- 요청 길이에 제한이 있어 전송할 수 있는 데이터의 크기가 작다 (약 3000자).
- 보안이 요구되지 않는 데이터의 전송에 적합하다. (ex : Google의 검색 쿼리 스트링)
- 북마크 가능하지만 민감한 정보 전송에는 적합하지 않다.
POST
- 폼 데이터를 HTTP 요청의 본문에 추가
- POST 메서드는 폼 데이터를 HTTP 요청의 본문에 포함시켜 전송하므로, URL에 데이터가 표시되지 않는다. 따라서 데이터가 URL에 노출되지 않아 보안이 강화된다.
- 특징:
- 전송할 데이터의 크기에 제한이 없다.
- 보안상 중요한 정보를 전송할 때 주로 사용된다 (예: 비밀번호).
- 결과 페이지를 북마크할 수 없다.
- Parameter (매개변수) - (name, value)
- 폼에서 전송되는 데이터는 이름(name)과 값(value) 쌍으로 표기된다.
name=fname&value=john
//fname 이라는 name 에 john 라는 데이터를 입력함
- HTML 폼 요소에서 각각의 입력 필드는 name 속성을 가져야 하며, 서버에서 이 값을 사용하여 데이터를 처리한다.
* 참고 링크
Javascript
DOM Manipulation
*참고링크
- DOM(Document Object Model) : HTML 문서의 구조를 객체 형태로 표현한 것
- DOM Manipulation : 웹 페이지의 구조를 동적으로 수정하고, 요소를 추가하거나 제거하며, 스타일이나 콘텐츠를 변경하는 과정
웹 페이지에서는 Javascript 를 통해 DOM 을 조작하여 HTML 요소를 조작하고 이벤트 처리 등을 할 수 있다.
웹 페이지의 모든 요소(HTML 태그)는 노드로 표현된다. DOM은 문서의 구조를 트리 형태로 모델링하여 각 요소를 프로그래밍적으로 조작할 수 있게 해준다.
노드의 종류
- Element Node (요소 노드):
- HTML 태그를 나타낸다. 예를 들어, <div>, <p>, <a> 등은 모두 요소 노드이다.
- 요소 노드는 자식 노드를 가질 수 있다.
- Text Node (텍스트 노드):
- 요소 노드 내의 텍스트를 나타낸다. 예를 들어, <p>Hello</p>에서 "Hello"는 텍스트 노드이다.
- 텍스트 노드는 항상 요소 노드의 자식으로 존재한다.
- Attribute Node (속성 노드):
- 요소의 속성을 나타낸다. 예를 들어, <img src="image.jpg" alt="image">에서 src와 alt는 속성 노드이다.
- 속성 노드는 직접적으로 접근할 수 없고, 요소 노드를 통해 접근한다.
- Comment Node (주석 노드):
- HTML 주석을 나타낸다. 예를 들어, <!-- This is a comment -->는 주석 노드이다.
노드의 구조
DOM은 트리 구조로 구성되어 있으며, 각 노드는 부모, 자식, 형제 관계를 가질 수 있다.
- 부모 노드(Parent Node): 다른 노드를 포함하는 노드이다.
- 자식 노드(Child Node): 부모 노드에 포함된 노드이다.
- 형제 노드(Sibling Node): 같은 부모를 가진 노드이다.
노드 조작
JavaScript를 사용하여 DOM 노드를 조작할 수 있다.
- document.createElement(tagName): 새로운 요소 노드를 생성한다.
- appendChild(node): 특정 노드의 자식으로 다른 노드를 추가한다.
- removeChild(node): 특정 노드를 부모 노드에서 제거한다.
- querySelector(selector): 선택자에 해당하는 첫 번째 노드를 찾는다.
Node 의 속성
- nodeName
- 설명: 노드의 이름을 반환한다. 요소 노드의 경우 태그 이름을 반환하며, 대문자로 출력된다.
- 예시: <div> 노드의 경우 nodeName은 "DIV"이고, <p> 노드는 "P"이다.
- nodeType
- 설명: 노드의 유형을 나타내는 숫자를 반환한다. 여러 종류의 노드에 대해 고유한 숫자가 있다.
- 요소 노드: 1
- 속성 노드: 2
- 텍스트 노드: 3
- 주석 노드: 8
- 문서 노드: 9
- 예시: <div>의 nodeType은 1, 텍스트 노드의 nodeType은 3이다.
- 설명: 노드의 유형을 나타내는 숫자를 반환한다. 여러 종류의 노드에 대해 고유한 숫자가 있다.
- parentNode
- 설명: 현재 노드의 부모 노드를 반환한다. 부모가 없는 경우(document의 루트 노드 등) null을 반환한다.
- 예시: <p> 노드의 parentNode는 해당 <p>를 포함하고 있는 <div> 노드이다.
- childNodes
- 설명: 현재 노드의 모든 자식 노드를 포함하는 노드 리스트(NodeList)를 반환한다. 이 리스트는 유사 배열 형태로, length 속성을 통해 자식 노드의 개수를 알 수 있다.
- 예시: <div> 요소가 두 개의 <p> 자식을 가진 경우, childNodes는 이 두 개의 <p> 노드를 포함하는 리스트를 반환한다.
- firstChild
- 설명: 현재 노드의 첫 번째 자식 노드를 반환한다. 자식이 없는 경우 null을 반환한다.
- 예시: <div> 안에 <p>가 첫 번째 자식인 경우, firstChild는 그 <p> 노드를 반환한다.
- lastChild
- 설명: 현재 노드의 마지막 자식 노드를 반환한다. 자식이 없는 경우 null을 반환한다.
- 예시: <ul> 안에 여러 개의 <li>가 있을 때, lastChild는 마지막 <li> 노드를 반환한다.
- nextSibling
- 설명: 현재 노드의 다음 형제 노드를 반환한다. 다음 형제가 없는 경우 null을 반환한다. 텍스트 노드와 같은 공백 노드도 포함된다.
- 예시: <p> 다음에 있는 <h1> 노드가 있을 경우, nextSibling은 그 <h1> 노드를 반환한다.
- previousSibling
- 설명: 현재 노드의 이전 형제 노드를 반환한다. 이전 형제가 없는 경우 null을 반환한다. 마찬가지로 텍스트 노드도 포함된다.
- 예시: <h1> 노드 앞에 있는 <p> 노드가 있을 경우, previousSibling은 그 <p> 노드를 반환한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Node 속성 예제</title>
</head>
<body>
<div id="container">
<p>첫 번째 문장</p>
<p>두 번째 문장</p>
</div>
<script>
const container = document.getElementById('container');
// nodeName
console.log(container.nodeName); // "DIV"
// nodeType
console.log(container.nodeType); // 1
// parentNode
console.log(container.parentNode.nodeName); // "BODY"
// childNodes
console.log(container.childNodes.length); // 3 (2개의 <p> + 1개의 텍스트 노드)
// firstChild
console.log(container.firstChild.nodeName); // "#text" (공백 텍스트 노드)
// lastChild
console.log(container.lastChild.nodeName); // "#text" (공백 텍스트 노드)
// nextSibling
const firstParagraph = container.firstChild.nextSibling; // 첫 번째 <p>
console.log(firstParagraph.nodeName); // "P"
// previousSibling
const secondParagraph = firstParagraph.nextSibling; // 두 번째 <p>
console.log(secondParagraph.previousSibling.nodeName); // "P"
</script>
</body>
</html>
DOM 조작 방법
- 요소 선택
getElementById: 특정 ID를 가진 요소 선택
const container = document.getElementById('container');
getElementsByClassName: 특정 클래스를 가진 요소들 선택
const paragraphs = document.getElementsByClassName('my-class');
getElementsByTagName: 특정 태그 이름을 가진 요소들 선택
const divs = document.getElementsByTagName('div');
querySelector 및 querySelectorAll: CSS 선택자를 사용하여 요소 선택
- querySelector:
- CSS 선택자를 사용하여 첫 번째 요소를 선택한다.
- 반환 값은 선택된 요소의 참조이다. 요소가 없으면 null을 반환한다.
- querySelectorAll:
- CSS 선택자를 사용하여 모든 요소를 선택한다.
- 반환 값은 NodeList로, 선택된 요소들의 리스트이다. 배열 메서드를 사용할 수 없다.
const firstParagraph = document.querySelector('p');
const allDivs = document.querySelectorAll('div');
- 요소 생성 및 추가
const newParagraph = document.createElement('p'); // 새로운 p 요소 생성
newParagraph.textContent = 'This is a new paragraph.'; // 텍스트 추가
container.appendChild(newParagraph); // container 안에 추가
- 요소 수정
const heading = document.querySelector('h1');
heading.textContent = 'Welcome!'; // 텍스트 변경
heading.style.color = 'blue'; // 스타일 변경
- 요소 제거
const paragraphToRemove = document.querySelector('p');
paragraphToRemove.remove(); // 선택한 p 요소 제거
- 이벤트 등록
EventListener:
- addEventListener 메서드를 사용하여 이벤트를 추가한다.
- 여러 이벤트를 동일한 요소에 추가할 수 있다.
- 이벤트 핸들러를 제거할 수 있는 removeEventListener 메서드가 있다.
const button = document.querySelector('button');
button.addEventListener('click', () => {
alert('Button clicked!');
});
onClick:
- 요소의 onclick 속성을 사용하여 이벤트를 추가한다.
- 한 요소에 하나의 이벤트 핸들러만 설정할 수 있다. 기존 핸들러가 덮어씌워진다.
button.onclick = () => {
alert('Button clicked!');
};
Event Loop:
- Event Loop는 JavaScript의 비동기 처리를 관리하는 핵심 메커니즘이다.
- 이벤트 루프는 콜 스택과 이벤트 큐를 관리하면서 비동기 작업의 콜백을 순차적으로 실행한다.
- 이를 통해 JavaScript는 사용자 인터페이스를 동적으로 업데이트하고, 비동기 작업을 효과적으로 처리할 수 있다.
이벤트 루프의 구조
JavaScript는 기본적으로 싱글 스레드로 작동한다. 즉, 한 번에 하나의 작업만 수행할 수 있다. 하지만 비동기 작업(예: AJAX 요청, 타이머 등)을 처리하기 위해 JavaScript는 다음과 같은 구조를 사용한다.
- 콜 스택(Call Stack):
- 현재 실행 중인 함수들이 쌓이는 스택이다.
- 함수가 호출되면 스택에 푸시(push)되고, 실행이 끝나면 스택에서 팝(pop)된다.
- 예를 들어, A 함수가 B 함수를 호출하면, B가 실행되는 동안 A는 콜 스택에서 대기한다.
- 힙(Heap):
- 동적으로 할당된 메모리 공간이다. 객체나 배열과 같은 데이터가 저장된다.
- 이벤트 큐(Event Queue):
- 비동기 작업의 콜백 함수가 대기하는 큐다.
- 비동기 작업이 완료되면 해당 콜백 함수가 이벤트 큐에 추가된다.
- 이벤트 루프(Event Loop):
- 콜 스택이 비어 있을 때 이벤트 큐에서 대기 중인 콜백 함수를 콜 스택으로 가져오는 역할을 한다.
- 이 과정을 반복하면서 비동기 작업의 결과를 처리한다.
console.log('Start'); // 1. 호출 스택에 추가되어 바로 실행
setTimeout(() => {
console.log('Timeout'); // 4. 타이머가 완료되면 콜백 큐에 추가되고, 이벤트 루프가 호출 스택이 비어 있을 때 실행
}, 0);
Promise.resolve().then(() => {
console.log('Promise'); // 3. 호출 스택이 비어 있을 때 실행 (실제로는 마이크로태스크 큐에서)
});
console.log('End'); // 2. 호출 스택에 추가되어 바로 실행
Start
End
Promise
Timeout
- console.log('Start')와 console.log('End')는 즉시 실행되어 콜 스택에서 처리된다.
- setTimeout은 비동기 작업이므로, 콜백 함수는 이벤트 큐에 추가된다.
- Promise.resolve().then()은 다음 이벤트 루프 사이클에서 실행될 준비가 되며, 먼저 이벤트 큐에 추가되기 전에 처리된다.
- 마지막으로, 이벤트 루프가 콜 스택이 비어있을 때 이벤트 큐에서 Promise 콜백을 실행하고, 그 다음에 Timeout 콜백을 실행한다.
- 함수 호출: 코드가 실행되면, 함수가 호출되면서 콜 스택에 추가됩니다.
- 비동기 작업: 비동기 작업이 발생하면, 해당 작업은 이벤트 큐에 콜백 함수를 추가합니다. 이 작업은 백그라운드에서 진행됩니다(예: 데이터 fetching).
- 콜 스택 비우기: 현재 실행 중인 모든 함수가 끝나고 콜 스택이 비어지면, 이벤트 루프가 이벤트 큐를 확인합니다.
- 이벤트 큐 처리: 이벤트 큐에 대기 중인 콜백이 있다면, 그 콜백을 콜 스택으로 가져와 실행합니다.
Javascript 문법
var와 let의 차이
- var: 함수 스코프(function scope)를 가지며, 재선언이 가능하다. 호이스팅(hoisting)되어 코드의 상단으로 끌어올려진다.
- let: 블록 스코프(block scope)를 가지며, 재선언이 불가능하다. 호이스팅되지만, 초기화 전에는 접근할 수 없다.
function varVsLet() {
if (true) {
var x = 'var variable';
let y = 'let variable';
}
console.log(x); // "var variable"
// console.log(y); // ReferenceError: y is not defined
}
varVsLet();
const
- 상수(constant)를 정의할 때 사용된다. 블록 스코프를 가지며, 재할당이 불가능하지만 객체의 속성은 변경할 수 있다.
const PI = 3.14;
console.log(PI); // 3.14
// PI = 3.14159; // TypeError: Assignment to constant variable.
const obj = { name: 'Alice' };
obj.name = 'Bob'; // 가능
console.log(obj.name); // "Bob"
특성 | var | let | const |
스코프 | 함수 스코프(function scope) | 블록 스코프(block scope) | 블록 스코프(block scope) |
재선언 | 가능 | 불가능 | 불가능 |
재할당 | 가능 | 가능 | 불가능 (단, 객체의 속성은 변경 가능) |
호이스팅 | 호이스팅됨 (초기화 전 접근 가능) | 호이스팅되지만 초기화 전 접근 불가 | 호이스팅되지만 초기화 전 접근 불가 |
사용 예 | var x = 10; | let y = 20; | const z = 30; |
ES5의 Array 관련 메소드
- forEach: 배열의 각 요소에 대해 주어진 함수를 실행한다.
- map: 배열의 각 요소에 대해 주어진 함수를 호출하여 새로운 배열을 생성한다.
- filter: 주어진 함수의 조건을 만족하는 요소만 포함한 새로운 배열을 생성한다.
- reduce: 배열의 각 요소를 누적하여 단일 값을 반환한다.
const numbers = [1, 2, 3, 4, 5];
// forEach
numbers.forEach(num => console.log(num * 2)); // 2, 4, 6, 8, 10
// map
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// reduce
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
rest Parameter
- 함수의 매개변수에서 나머지 인수를 배열로 받을 수 있게 해준다.
function sum(...args) {
return args.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10, 15)); // 30
Arrow function
- 간결한 문법으로 함수를 정의할 수 있으며, this 바인딩이 lexically(어휘적으로) 결정된.
const add = (a, b) => a + b;
console.log(add(5, 3)); // 8
const array = [1, 2, 3];
const squares = array.map(num => num * num);
console.log(squares); // [1, 4, 9]
- 함수가 일급 객체로, 변수에 할당되거나, 인수로 전달되거나, 반환값으로 사용될 수 있다.
function greet() {
return 'Hello!';
}
const welcome = greet; // 함수 할당
console.log(welcome()); // "Hello!"
function higherOrderFunction(fn) {
return fn();
}
console.log(higherOrderFunction(greet)); // "Hello!"
Object의 개념
- 객체는 키-값 쌍으로 구성된 데이터 구조이다. 프로퍼티와 메서드를 가질 수 있으며, 복잡한 데이터를 표현하는 데 사용된다.
const person = {
name: 'Alice',
age: 30,
greet() {
return `Hello, my name is ${this.name}`;
}
};
console.log(person.name); // "Alice"
console.log(person.greet()); // "Hello, my name is Alice"