TIL0529 (DOM,이벤트,객체와 인스턴스,콜백함수,화살표함수,map,filter,reduce

뿌링클 치즈맛·2023년 5월 29일
0

Elice AI트랙 8기

목록 보기
11/28

DOM(Document Object Model)

DOM: 브라우저가 이해할 수 있는 자료구조. html태그 아래에 head태그가 있고, head태그의 아래에는 title,meta태그가 있음.

DOM 구성요소

<div class='Hi'>World</div>
<!--div는 요소노드, class='Hi'는 어트리뷰트노드, World는 텍스트 노드로 파싱(변환)됨-->

노드 객체 타입 (총 12개)

  • 문서 노드 (document node)
  • 요소 노드 (element node)
  • 어트리뷰트 노드 (attribute node)
  • 텍스트 노드 (text node)
  • 주석 노드 (comment node)

DOM에서 요소노드 검색/생성하기
요소 노드(element node)를 검색 및 생성할 수 있다!

  • 먼저 구하는 방법부터 알아보자!
  • id를 이용한 요소 노드 구하기
  • 태그 이름을 이용한 요소 노드 구하기
  • class를 이용한 요소 노드 구하기
  • css 선택자를 이용한 요소 노드 구하기
    -id,클래스가 모두 없을 경우에는
  • querySelector
  • querySelectorAll
const elems = document.querySelectorAll('ul');

console.log(elems[0].children); //li 출력
console.log(elems[0].parentNode); //ul 상위 태그 출력

HTML Collection과 Node List

  • DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체
  • 유사 배열 객체이면서 이터러블(전개구문을 붙일 수 있음)
  • 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는 객체
    상태 변경과 상관없이 안전하게 사용하기 위해서는 HTML콜렉션과 노드리스트를 배열로 변환해 사용하는 것이 좋다!

HTML Collection

노드 객체의 상태 변화를 실시간으로 반영하는 live 객체

const elems =document.getElementsByClassName('red');
// 이 시점에 HTMLCollection 객체에는 클래스에 red가 포함된 red banana, red apple, red orange 3개의 요소 노드가 담겨 있다.
console.log(elems); 
//HTMLCollection(3) [li#apple.fruit.apple.red, li#banana.fruit.banana.red, li#orange.fruit.orange.red]

for (let i = 0; i < elems.length; i++) {
    elems[i].className = 'blue';
}
// HTMLCollection 객체의 모든 요소의 class 값을 'blue'로 변경한다.

위의 for문은 모든 태그를 blue로 바꾸지 않는다. 그 이유는
첫번째로 for문이 실행되면, 태그가 red인 것이 2개로 줄어 elems.length가 2가 되기 때문이다. 그리고 두번째로 for문이 실행될 때, i는 1이 되고, elems.length는 2이므로 1번자리인 orange만 파란색이 되고 for문이 종료된다.
이는 HTML Collection가 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는 객체이기 때문이다.

const elem=[...document.getElementsByClassName('red')];

HTML콜렉션을 배열로 만들 수 있다. 배열로 만들어진 HTML 콜렉션은 노드 객체의 상태가 바뀌어도 반영되지 않는다.

Node List
노드 객체의 상태 변화를 실시간으로 반영하지 않는 객체
하지만 childNotes 프로퍼티가 반환하는 노드 리스트는 HTML 콜렉션처럼 실시간으로 노드의 상태를 live하게 반영한다.
querySelectorAll은 노드리스트를 반환한다!

+) 전개구문

const arr=[1,2,3];
console.log(...arr) //1 2 3
console.log(arr) //[1,2,3]

console.log(Math.max(arr)); //NaN
console.log(Math.max(...arr));

...arr를 사용하면 arr안에 있는 값을 전개할 수 있다.

const elems=document.getElementsByClassName('gray');
console.log([...elems]);
[...elems].forEach(el->el.style.color='gray');

마지막의 [ . . .]를 해주는 이유는 배열로 출력하기 위함이다.

DOM 조작


document.createElement로 원하는 태그를 생성하고 ul변수에 ul태그를 선택하는 선택자를 저장, li에 textContent 메서드를 사용해 '키위'추가, ul에 appendChild 메서드로 변수 li를 넣어줌.

let apple=document.querySelector('#apple');
ul.insertBefore(li,apple)

insertBefore(넣고싶은 것, 넣어줄 곳)을 사용하면 특정한 위치 앞에 태그를 넣어줄 수 있다.

console.log(li.firstChild.nodeValue);
console.log(li.textContent);

두 코드는 같은 내용을 출력한다. 하지만 nodeValue를 사용하면 firstChild를 참조한 후에 수정해야 하기 때문에 번거롭다.

for Each

const n=[1,2,3,4,5];
for (let i=0;i<n.length;i++)
  	console.log(n[i]); 

n.forEach(function(n){
          console.log(n)});

n.forEach(n=>console.log(n));

forEach메소드는 배열의 요소를 반복하며 함수 (console.log)를 호출한다. for문보다 짧고 간편하다.

Event

마우스 클릭, 스크롤링, 텍스트박스 입력 등 사용자가 브라우저와 상호작용하면서 발생하는 사건.

이벤트핸들러 속성(어트리뷰트) 방식

<button onclick="sayHi('Park')">Click me!</button>

//javascript
function sayHi(name){
	console.log(`Hi ${name}`);}

버튼요소에 onclick이라는 프로퍼티가 있고, 그 프로퍼티에 sayHi라는 함수를 할당한다.

button.addEventListener('click',function(){
	console.log('Button is Clicked')});

addEventListener는 함수다. 이때 addEventListener에 매개변수로 들어간 함수는 콜백함수다! 아래에 자세하게 적어뒀다.

이벤트 전파
Capturing->Target->Bubbling

이벤트가 캡쳐링을 통해 타겟으로 이동하고, 다시 버블링으로 최상위 노드까지 올라간다.
전파:이벤트가 발생했음을 태그들에게 전달.
내려가는게 Capture, 이벤트가 발생후 다시 타고 올라가는걸 Bubble. 올라갈 때 이벤트가 발생했던 것을 위의 태그들에게 전달하면서 이벤트를 발생시키는 것.

preventDefault: DOM요소의 기본 동작을 중단 (input에 입력을 해도 입력창에 아무 표시도 되지 않음)

이벤트 전파를 중지하기 위한 방법:
객체.stopPropagation:

이벤트 위임

여러개의 하위 DOM요소에 이벤트 핸들러를 등록하는 대신 상위 이벤트 DOM요소에 이벤트 핸들러를 등록하는 방법.

//HTML
<ul id='fruits'>
  <li id='mango'>Mango</li>
  <li id='strawberry'>Strawberry</li>
  <li id='grape'>Grape</li>




const fruits = document.getElementById('fruits');
//fruits라는 id를 가진 요소들을 가져옴
const msg = 'SOLD OUT';

function msgAdd() {
    [...fruits.children].forEach(fruit => {
        fruit.textContent = msg;
    });
}

// 모든 내비게이션 아이템(li 요소)에 이벤트 핸들러를 등록한다.
document.getElementById('mango').addEventListener('click', msgAdd);
document.getElementById('strawberry').addEventListener('click', msgAdd);
document.getElementById('grape').addEventListener('click', msgAdd);
//각 리스트를 클릭시 SOLD OUT 으로 li에 있던 값들이 바뀜


fruits.addEventListener('click',msgAdd)

굳이 li태그의 값들에 다 addEventListener를 할 필요 없이 상위태그인 fruits에만 넣어줘도 적용됨!

객체와 인스턴스

생성자함수로 마동석을 여러명 만들 수 있음

생성자 함수(constructor): new 연산자와 함께 호출하여 인스턴스를 만드는 함수


function Cat(meow) {
  // 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
  this.name = '삼색이';
  this.meow = '냥';
  this.say = function () {
    return this.name+'는' + this.meow + ;
  };
}

const Samsaek = new Cat('냐옹');  // '냐옹'이라고 하는 삼색 인스턴스 생성
console.log(Samsaek.say())//삼색이는 냥
//say()로 사용하는 것은 함수이기 때문!

new는 생성자함수를 통해 인스턴스를 만들때 사용됨. 인스턴스는 new를 통해 만들어진 복사본_1,복사본_2라고 이해했다.

함수 심화내용

함수는 일급 객체다
  • 다음 조건을 만족하면 일급 객체라고 한다.
  • 무명의 리터럴(function myFunction같은)로 생성할 수 있다.
  • 변수나 자료구조(객체, 배열)에 저장할 수 있다.
    let add=function(a,b){};
  • 함수의 매개변수에 전달할 수 있다. (콜백함수)
  • 함수의 반환값으로 사용할 수 있다.

콜백함수
-함수에 파라미터로 들어가는 함수
-콜백 함수는 순차적으로 실행하기 위한 용도로 많이 쓰인다.

function first(){
  //API 호출 비동기 작업을 하는 함수
  console.log(1);
}
function second(){
  console.log(2);
}
first();
second();
function first(f) { //<-- 얘가 고차함수
  console.log(1);
  console.log(f); 
  //이건 f second(){console.log(2);}나옴
  f(); //f를 호출
}

function second() { //<-- 얘가 콜백함수
  console.log(2);
}

first(second);
//first함수 내에 매개변수로 받은 f를 다시 호출하는 부분이 있어 second를 호출해 실행함
first(second()); //second가 값으로 전달이 되었는데 다시 함수로 사용할 수는 없나?

화살표 함수

-기존의 함수 정의 보다 간략하게 함수를 정의하는 것
-함수 선언문으로 정의할 수 없고 함수 표현식으로 정의해야 한다.
함수 선언문: function myFunc
함수 표현식: let myFunc=function

let addArrow = (x,y) => {
  return x + y;
}
//function addArrow 없이 바로 함수를 정의할 수 있음

addArrow=(x,y)=>x+y;
//이것도 똑같음

let functionName=(x,y)=>{ }의 형식이다.

if (a>b)
	console.log(a)
else
	console.log(b)

아래에 코드가 한 줄일 경우 중괄호를 사용하지 않아도 된다.

화살표 함수와 일반 함수의 차이점

  • 화살표 함수는 인스턴스를 생성할 수 없다
    ->화살표 함수는 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다.
const Foo = () => {};

new Foo(); // TypeError: Foo is not a constructor
Foo.hasOwnProperty('prototype'); // -> false
  • 중복된 매개변수 이름을 선언할 수 없다
  • 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다
    ->일반 함수의 this와 다름

map,filter,reduce

const numbers = [1, 4, 9];
const roots = numbers.map(item => Math.sqrt(item));

const result=numbers.map(function(el){
  console.log(el)});
//[1,4,9] function의 반환값으로 구성된 새로운 배열 반환.
console.log(roots); 

const numbers = [1,2,3, 4,5, 9];
const r=numbers.filter(function(el){
  if (el%2){
    return false;}
  else{
    return true;}})
console.log(r) //[1,3,5,9]
//홀수일 경우에는 true를 반환하게 됨
// 이유: 홀수를 2로 나누면 나머지가 1인데, 1은 암묵적으로 true가 됨
//홀수로만 구성된 배열을 반환

Array()는 일종의 클래스.

자바스크립트 배열의 특징
배열 내부의 데이터 타입이 다를 수 있다.
배열의 크기가 동적으로 변경될 수 있다.

profile
뿌링클 치즈맛

0개의 댓글