DOM (Document Object Model)
- Document(html 파일)를 JS가 알아먹을 수 있는 Object형태로 Modellng 한 것
- 브라우저에 기본적으로 내장, 브라우저 환경에서만 돌아감
- 브라우저 환경: 확인 가능
- node 환경: 확인 불가능 (ex: vscode)
- 브라우저의 요소들에 접근하고 조작하는 방법을 제공
- 속성: 객체의 상태나 특징을 나타내는 값을 저장하는 변수 (예: a.id)
- 메소드: 객체가 수행할 수 있는 동작이나 기능을 나타내는 함수
// 접근
// id 값에 해당하는 요소에 접근하여 값을 반환
document.getElementById("id");
// class 값에 해당하는 요소에 접근하여 값을 반환
document.getElementsByClassName("className");
// 태그 값에 해당 하는 모든 또는 하나의 요소에 접근하여 값을 반환
document.getElementsByTagName("tagName"); // 모두
document.getElementByTagName("tagName"); // 하나
// css 선택자에 해당하는 첫 번째 요소에 접근하여 값을 반환
document.querySeletor("#id");
// parentElement: 부모, children: 자식
// css 선택자에 해당하는 모든 요소에 접근하여 배열로 값을 반환
document.querySelectorAll("#id");
// 제어
// 요소 추가 방법
const newDiv = document.createElement('div');
document.body.append(newDiv);
// 요소 변경
document.querySeletor('ul').children[1].innerText = '내용 변경';
document.getElementByTagName('h1')[0].innerText = '제목 변경';
document.querySeletor('').setAttribute("style", "background-color: red;");
// 속성
// innerHTML: 요소의 내부 HTML 콘텐츠를 나타내는 속성
// textContent: 요소의 텍스트 콘텐츠를 나타내는 속성
// appendChild(node): 주어진 노드를 현재 요소의 자식으로 추가
// removeChild(node): 주어진 노드를 현재 요소의 자식에서 제거
// setAttribute(name, value): 요소에 지정된 이름과 값을 가진 속성을 추가
// addEventListener(event, handler): 요소에 이벤트 핸들러를 등록
class
- 객체지향
- 클래스: 설계도
- 인스턴스: 설계도를 바탕으로 만들어진 객체
// 클래스 생성: 객체를 정확하고 빠르게 만들 수 있도록 도와준다.
class Person {
// 생성자 함수: 필수 요소들을 넣어줘야 함.
constructor(name, age) {
// this: 우리가 만들 실체
this.name = name;
this.age = age;
}
// 메서드 형태의 동사 표현
sayHello() {
console.log(this.name + ' hello');
}
}
// 인스턴스 만들기
const person1 = new Person('홍길동', '30');
const person2 = new Person('홍길순', '25');
// 메서드 호출
person1.sayHello(); // 홍길동 hello
person2.sayHello(); // 홍길순 hello
Getters와 Setters
- 사용하는 이유
- 데이터 은닉
- 객체 내부 상태를 보호하여 데이터 은닉을 구현하는 데 도움을 줌
- 유효성 검사
- Setter를 사용하여 값을 할당할 때, 값을 검증하고 유효성을 확인할 수 있음
- 계산된 속성
- Getter를 사용하여 속성 값을 동적으로 계산할 수 있음
class Car {
// 생성자
constructor (modelName) {
this._modelName = modelName;
}
// 모델 이름
get modelName() {
return this._modelName;
}
set modelName(val) {
if (val.length <= 0) { // 유효성 검사
console.log('error');
return;
}
else if (typeof val !== 'string') {
console.log('type error');
return;
}
this._modelName = val;
}
printModelName () {
console.log(`${this.modelName} 은 ${this.modelYear}년에 출시`);
}
}
const car1 = new Car("sorento");
car1.printModelName(); // sorento
상속
- 하나의 클래스가 다른 클래스의 특성과 동작을 상속 받아 사용할 수 있음
- 특징
- 코드의 재사용성 높임
- 재정의 (오버라이딩) : 자식 클래스에서 부모 클래스의 메소드를 다시 정의
- 구조화 촉진
- 객체 간의 계층적인 관계 구축 가능
- 생성자 (super)
- 부모 클래스의 생성자 또는 메소드를 호출하기 위해 사용되는 특별한 키워드
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log('Animal speaks.');
}
}
class Cat extends Animal {
constructor(name, color) {
super(name); // 부모 클래스의 생성자 호출
this.color = color;
}
speak() {
super.speak(); // 부모 클래스의 메소드 호출
console.log('Cat meows.');
}
}
// 호출
const cat = new Cat('Kitty', 'white');
cat.speak();
정적 메소드
- 객체의 인스턴스와 관련없이 클래스 자체에 속하는 메소드
- 클래스의 인스턴스를 생성하지 않고도 직접 호출 가능
class Calculator {
static add(a, b) {
console.log(a, b);
}
}
Calculator.add(1, 2);
클로저 (Closure)
- 함수가 선언될 때의 환경을 기억하여 그 함수가 선언된 위치와 상관없이 외부 변수에 접근할 수 있게 해줌
- 렉시컬 스코프 (Lexical scope)
- 자신이 선언된 위치에 따라 변수에 접근할 수 있는 스코프를 가짐
- JS엔진은 함수를 어디서 '호출' 했는지가 아니라, 어디에 '정의' 했는지에 따라서 스코프 (상위 스코프)를 결정
function outerFunction() {
let outerVariable = 'I am from the outer function';
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
const closure = outerFunction();
closure(); // 출력: I am from the outer function