블로그
전체 2#카테고리
- 프론트엔드
#태그
- 인프런워밍업스터디클럽
- FE
- 1기
- 발자국
2024. 05. 12.
0
[인프런 워밍업 스터디 클럽 1기] FE 2주차 발자국
시작강의가 좀 밀려있긴 한데... 기간 안엔 다 들을 수 있을 거라 생각하며 차근차근 정리 중이다...정리자바스크립트 this 키워드메서드 내 this ⇒ 해당 객체(Object)함수 내 this ⇒ window 객체생성자 함수 내 this ⇒ 빈 객체(해당 인스턴스)forEach문 내 this ⇒ 두 번째 매개 변수 값, 없을 경우 window 객체 또는 해당 객체화살표 함수 내 this ⇒ 상위 스코프의 this예제메서드 내 ⇒ 해당 객체(Object)const audio = { title: 'a', play() { console.log('play this', this); }, }; audio.stop = function () { console.log('stop this', this); }; audio.play(); //play this { title: 'a', play: f } audio.stop(); //play this { title: 'a', play: f } 함수 내 ⇒ window 객체function playAudio() { console.log(this); } playAudio(); // Window 객체 생성자 함수 내 ⇒ 빈 객체(해당 인스턴스)function Audio(title) { this.title = title; // 이게 없으면 빈 객체 console.log(this); } const audio = new Audio('a'); // Audio { title: 'a' } forEach문 내 ⇒ 두 번째 매개 변수 값, 없을 경우 window 객체 또는 해당 객체const audio = { title: 'audio', categories: ['rock', 'pop', 'hiphop'], displayCategories() { this.categories.forEach(function (category) { console.log(`title: ${this.title}, category: ${category}`); // 함수 내에 있기 때문에 window 객체를 가리킴 }); }, }; audio.displayCategories(); const audio2 = { title: 'audio', categories: ['rock', 'pop', 'hiphop'], displayCategories() { this.categories.forEach( function (category) { console.log(`title: ${this.title}, category: ${category}`); }, { title: 'audio' } ); // forEach 두 번째 매개변수에 있는 값을 참조시킬 수 있음 }, }; audio2.displayCategories(); const audio3 = { title: 'audio', categories: ['rock', 'pop', 'hiphop'], displayCategories() { this.categories.forEach( function (category) { console.log(`title: ${this.title}, category: ${category}`); }, this // audio3 해당 객체를 참조 ); }, }; audio3.displayCategories(); 화살표 함수 내 ⇒ 상위 스코프의 thisconst audio = { title: 'audio', categories: ['rock', 'pop', 'hiphop'], displayCategories() { this.categories.forEach(function (category) { console.log(`title: ${this.title}, category: ${category}`); // 상위 스코프의 this(Lexical this) => audio { title : 'audio', categories: Array(3) } }); }, }; audio.displayCategories(); call, apply, bind함수에서 this 사용 시, window 객체가 아닌 값을 참조시키기 위해 사용함수명.call(thisArg[, arg1, arg2, ...]) : 함수를 호출하는 함수함수를 호출할 때, 첫 번째 매개 변수에 함수 내에서 사용할 this 값을 지정할 수 있음첫 번째 매개 변수로 null 또는 undefined가 전달되면 전역 객체가 this로 사용됨두 번째 ~ … 매개 변수로 호출할 함수에 전달될 인수 추가 가능const fullName = function (arg1, arg2) { console.log(`${this.firstName} ${this.lastName}`); console.log(`${arg1} ${arg2}`); }; const person = { firstName: 'Im', lastName: 'Hass', }; fullName.call(person, '매개변수1', '매개변수2'); // Im Hass // 매개변수1 매개변수2 함수명.apply(thisArg[, argArray]) : call()과 동일call()과 인수를 배열로 넣어주는 차이const fullName = function (arg1, arg2) { console.log(`${this.firstName} ${this.lastName}`); console.log(`${arg1} ${arg2}`); }; const person = { firstName: 'Im', lastName: 'Hass', }; fullName.apply(person, ['매개변수1', '매개변수2']); **함수명.bind(thisArg)**: 함수가 실행되지 않고 바인딩만 시켜줌함수를 바인딩할 때, 새로운 함수를 생성함 → 원본 함수와 동일한 코드를 가지지만 this가 바인딩된 값이 들어감 ⇒ 새로운 변수에 담거나 즉시 실행 시켜서 사용해야 함function func(language) { if (language === 'kor') { console.log(`language: ${this.korGreeting}`); } else { console.log(`language: ${this.engGreeting}`); } } const greeting = { korGreeting: '안녕', engGreeting: 'Hello', }; // 원본은 변하지 않기 때문에 undefined 출력 // func.bind(greeting); // func('kor'); // language: undefined // 1. 새 변수에 담아서 사용하기 // const boundFunc = func.bind(greeting); // boundFunc('kor'); // language: 안녕 // 2. 즉시 실행하기 func.bind(greeting)('kor'); Event Loop자바스크립트는 동기 언어지만, 다른 것의 도움(브라우저의 자바스크립트 엔진 또는 Node.js와 같은 런타임 환경)을 통해 비동기로 처리할 수 있음.ex) setTimeout(브라우저 api-window object 또는 node api-global object)setTimeout에 설정된 값이 0(즉시 실행)이어도 콜백 큐에서 호출 스택이 비어야 들어가기 때문에 순서가 다르게 출력됨자바스크립트 코드를 실행하기 위해 엔진이 필요한데, 자바스크립트 엔진에는 메모리 힙, 콜 스택 두 가지 주요 구성 요소가 있음Call Stack(호출 스택)코드 실행에 사용되는 메모리 구조함수 호출 및 반환을 추적함코드가 실행될 때 함수 호출은 스택에 추가되고, 함수가 완료되면 스택에서 제거됨Callback Queue(콜백 큐)비동기 작업의 콜백 함수들이 대기하는 대기열비동기 작업이 완료되면 해당 콜백 함수가 콜백 큐에 추가됨Event Loop(이벤트 루프)콜 스택과 콜백 큐를 계속 모니터링하여 콜 스택이 비어있을 때 콜백 큐의 첫 번째 콜백을 콜 스택으로 이동시킴내부 진행 참고 사이트 : https://kamronbekshodmonov.github.io/JELoop-Visualizer/Closure외부 함수 보다 생명 주기가 긴 내부 함수 중에서, 종료된 외부 함수의 값을 참조할 수 있는 내부 함수를 의미한다.클로저 사용 전(오류: b에 접근 불가)let a = 'a'; function funcB() { let c = 'c'; console.log(a, b, c); } function funcA() { let b = 'b'; console.log(a, b); funcB(); } funcA(); // a b // ReferenceError: b is not defined 클로저 사용 후(해결: 내부 함수로 변경)let a = 'a'; function funcA() { let b = 'b'; console.log(a, b); function funcB() { let c = 'c'; console.log(a, b, c); } funcB(); } funcA(); // a b // a b c 구조 분해 할당배열이나 객체의 속성을 해체하여 개별 변수에 담을 수 있게 하는 Javascript 표현식객체 구조 분해 할당let person = { name: 'hass', age: 30, phone: '123', address: { zipcode: 1234, street: 'rainbow', number: 42, }, }; let { address: { zipcode, street, number } } = person; console.log(zipcode, street, number); 별명 지정let people = [ { name: 'mike', age: 35, family: { mother: 'Jane', father: 'Harry', sister: 'samantha', }, }, { name: 'Tom', age: 25, family: { mother: 'Norah', father: 'Richard', brother: 'Howard', }, }, ]; for (let { name: n, family: { father: f }, } of people) { console.log(`Name : ${n}, Father: ${f}`); } // Name : mike, Father: Harry // Name : Tom, Father: Richard Map() 메서드배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환함array.map(callback(currVal[, index[, array]]])[, thisArg])첫 번째 매개 변수로 callback 함수가 들어가고, 두 번째 매개 변수에 this 바인딩 가능Filter() 메서드주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환함array.filter(callback(element[, index[, array]])[, thisArg])첫 번째 매개 변수로 callback 함수가 들어가고, 두 번째 매개 변수에 this 바인딩 가능Reduce() 메서드배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환함arr.reduce(reducerFunction(acc, curr, idx, src), initalValue)reducerFunction 4개의 인자를 가짐누산기(acc)현재 값(curr)현재 인덱스(idx)원본 배열(src)예제const result = [0, 1, 2, 3, 4].reduce(function (acc, curr, idx, src) { return acc + curr; }, 10); // console.log(result); // 20 acc curr idx src return value 1번째 호출 10 0 0 [0, 1, 2, 3, 4] 10 2번째 호출 10 1 1 [0, 1, 2, 3, 4] 11 3번째 호출 11 2 2 [0, 1, 2, 3, 4] 13 4번째 호출 13 3 3 [0, 1, 2, 3, 4] 16 5번째 호출 16 4 4 [0, 1, 2, 3, 4] 20 undefiend vs null공통점둘 다 원시 자료형undefiend의 타입은 undefiend, null 타입은 null(object로 나옴, strit 모드는 null) 유일한 타입undefined아무 값도 할당받지 않은 상태개발자의 의도 X, 자바스크립트 엔진이 초기화한 값null비어있는 값, 존재하지 않는 값개발자가 의도한 값null을 할당하면 변수가 이전에 참조하던 값을 명시적으로 참조하지 않겠다고 하는 것이므로, 자바스크립트 엔진이 변수의 메모리 공간에 대해 가비지 콜렉션을 수행함얕은 비교(Shallow Compare)숫자, 문자 등 원시 자료형은 값으로 비교배열, 객체 등 참조 자료형은 참조되는 위치를 비교IdentifiersuserName seasons isFinished enemies userCall StackAddress Value 0012ASF “Hass” 3241AF 5 416UHDI true 1235JFT HHSYDW1462 JFFI12HA KHS18205JAHeapAddress Value HHSYDW1462 ["ene1", "ene2", "ene3"] KHS18205JA {name: "hass", profession: "Drug dealer"}깊은 비교(Deep Compare)객체의 경우에도 값으로 비교Object Depth가 깊은 경우 : lodash 라이브러리의 isEqual() 사용Obejct Depth가 깊지 않은 경우: JSON.stringfy() 사용const obj1 = { a: 'a', b: 'b' }; const obj2 = { a: 'a', b: 'b' }; console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true 얕은 복사, 얕은 동결얕은 복사 : 내부에 중첩된 값은 복사되지 않음(기존과 동일한 객체를 참조함, 하나를 변경하면 똑같이 변경됨)얕은 동결 : Object.freeze() 메서드, 객체를 동결하여 변경할 수 없도록 함.얕은 복사를 하는 연산자 : 전개 연산자, Oject.assign(), Array.from(), slice()깊은 복사내부 중첩된 값까지 복사함JSON.parse(JSON.stringify(object)) 또는 중첩된 부분에 전개 연산자 사용 { …aObj, cObj: {…aObj.cObj }}lodash 라이브러리를 활용structuredClone(object) 메서드 활용함수 선언문, 함수 표현식함수 표현식 : 함수를 만들고 변수에 할당, 익명 함수호이스팅 시, 함수 선언식만 영향을 받음함수 표현식은 인터프리터가 해당 코드 줄에 도달할 때만 로드됨함수 표현식은 정의된 로컬 변수의 복사본을 유지할 수 있도록 호이스팅 되지 않음즉시 호출(실행) 함수 표현식(IIFE(Immediately Invoked Function Expression))정의 하자마자 즉시 실행되는 함수를 의미함기본 형태 ( function () {} )()첫 번째 소괄호( ... ) : 전역 선언을 막고, IIFE 내부로 다른 변수의 접근을 막음두 번째 소괄호 …() : 즉시 실행 함수를 생성하는 괄호, 이를 통해 Javascript 엔진이 함수를 즉시 해석하고 실행함IIFE를 변수에 할당하면 IIFE 자체는 저장되지 않고, 함수가 실행된 결과만 저장할 수 있음IIFE로 Closure가 가능하게 만든 후, 내부 함수에서 외부 함수에 있는 변수에 접근되게 함사용 목적변수를 전역으로 선언하는 것을 피하기 위해IIFE 내부에 다른 변수들이 접근하는 것을 막기 위해익명 함수를 만들기 위해 (이름이 없기 위한 두 가지 조건 중 한 가지)이 함수를 할당 받을 변수를 지정해야 함이 함수를 즉시 호출해야 함// 이름은 선택 사항이라고 했지만 function 키워드로 만들 때 에러 발생 // function (a, b) { // Error: Identifier expected. // return a- b; // } // 조건1 const minus = function (a, b) { return a - b; }; // 조건2 (function (a, b) { return a - b; })(1, 2); IIFE 적용 전const score = () => { let count = 0; return { current: () => { return count; }, increment: () => { count++; }, reset: () => { count = 0; }, }; }; console.log(score); // () => {...} 함수 출력 console.log(score().current()); // 0 score.increment(); // count를 1 증가 시킴 console.log(score().current()); // 0 => score()를 다시 실행 시켜서 count가 0으로 초기화됐기 때문에 값이 증가하지 않음 IIFE 적용 후const score = (() => { let count = 0; return { current: () => { return count; }, increment: () => { count++; }, reset: () => { count = 0; }, }; })(); console.log(score); // { current: f, ... } console.log(score.current()); // 0 score.increment(); // count를 1 증가 시킴 console.log(score.current()); // 1 Intersection observer무한 스크롤, 이미지 lazy loading 등을 구현할 때 사용됨Lazy Loading 예제 Intersection Observer img { width: 400px; height: 300px; display: block; margin: 10px auto; } " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> " alt="placeholder image" data-src=""> const observer = new IntersectionObserver( function (entries, observer) { console.log('entries', entries); entries.forEach((entry) => { if (entry.isIntersecting) { // 루트 요소와 타겟 요소가 교차하면 console.log('옵저버'); entry.target.src = entry.target.dataset.src; // dataset에 있는 url을 src에 넣어줌 observer.unobserve(entry.target); // Lazy loading 후에는 observer 해제 } }); }, { threshold: 1 } // 타겟 요소가 루트 요소와 100% 겹치면 콜백 함수 실행 ); const imgEls = document.querySelectorAll('img'); console.log(imgEls); imgEls.forEach((img) => { observer.observe(img); }); 순수 함수(Pure Function)함수형 프로그래밍 패러다임의 한 부분특정 함수가 다른 함수에 미치는 예기치 못한 영향을 최소화하고, 함수를 만들고 실행할 때 어떤 결과값을 리턴할지 예측할 수 있다는 장점이 있음가능한 순수 함수를 사용하는 것이 좋음클린 코드를 위해서테스트를 쉽게 하기 위해서디버그를 쉽게하기 위해서독립적인 코드를 위해서두 가지 규칙이 있음같은 입력이 주어졌을 때, 언제나 같은 결과값을 리턴한다 (same input → same output)사이드 이펙트를 만들지 않는다 (동일한 input이지만 외부 값에 의해 변경되는 output → impure하게 만듦)커링(Curry Function)함수와 함께 사용하는 고급 기술 (다른 언어에도 존재하는 기술)f(a, b, c) 처럼 단일 호출로 처리하는 함수를 → f(a)(b)(c)와 같이 각각의 인수가 호출 가능한 프로세스로 호출된 후 병합될 수 있게 변환하는 것즉, 함수를 호출하는 것이 아닌 변환하는 것예제const sum = (x, y) => x + y; console.log(sum(10, 20)); // 30 const curriedSum = (x) => (y) => x + y; console.log(curriedSum(10)); // f() y => x + y console.log(curriedSum(10)(20)); // 30 const makeFood = (ingredient1) => { return (ingredient2) => { return (ingredient3) => { return `${ingredient1} ${ingredient2} ${ingredient3}`; }; }; }; // const hamburger = makeFood('Bread')('Ham'); // console.log(hamburger); // (ingredient3) => {...} 완성되지 않음 const hamburger = makeFood('Bread')('Ham')('Tomato'); console.log(hamburger); // Bread Ham Tomato => 3개의 인수를 다 넣어줘야 완성됨 // makeFood 축약 const cleanMakeFood = (ingredient1) => (ingredient2) => (ingredient3) => `${ingredient1} ${ingredient2} ${ingredient3}`; const newHamburger = cleanMakeFood('Bread')('Ham')('Tomato'); console.log(newHamburger); // Bread Ham Tomato // 일반 log 함수 function log(date, importance, message) { alert(`[${date.getHours()} : ${date.getMinutes()}]: [${importance} ${message}]`); } log(new Date(), 'DEBUG', 'same bug'); // 커리 함수 function curry(f) { return function (a) { return function (b) { return function (c) { return f(a, b, c); }; }; }; } const curriedLog = curry(log); curriedLog(new Date())('DEBUG')('same bug'); // 동적으로 추가되는 커리 함수 (매개 변수 개수 상관 없이 커리 함수로 변경 가능) function curry2(func) { return function curried(...args) { if (args.length >= func.length) { return func.apply(this.args); } else { return function (...args2) { return curried.apply(this, args.concat(args2)); }; } }; } // const sum = (x, y, z) => x + y + z; const sum = (x, y, z, j) => x + y + z + j; const curriedSum = curry2(sum); // console.log(curriedSum(1)(2)(3)); console.log(curriedSum(1)(2)(3)(4)); strict modeJavascript의 엄격 모드제한된 버전을 선택하여 암묵적인 “느슨한 모드(sloppy mode)”를 해제하기 위한 방법시멘틱스에 몇 가지 변경이 일어남기존에는 무시되던 에러를 throwingJavascript 엔진의 최적화 작업을 어렵게 만드는 실수를 바로 잡음. 가끔 엄격 모드의 코드가 비엄격 모드와 동일한 코드 보다 더 빠르게 작동하도록 만들어줌.적용 방법파일에 "use strict" 지시자 입력함수 안에 "use strict" 지시자 입력하여 해당 함수만 적용 가능class를 사용하면 자동으로 strict 모드 적용자바스크립트 파일의 타입을 module로 설정하면 strict 모드 적용기존과 차이점할당할 수 없는 값에 할당하려 할 때 ex) 선언되지 않은 변수, undefiend, NaN수정할 수 없는 값을 수정하려 할 때 ex) readOnly 객체동일한 이름의 파라미터가 존재할 때함수 내의 this가 undefiend가 됨
프론트엔드
・
인프런워밍업스터디클럽
・
FE
・
1기
・
발자국
2024. 05. 05.
0
[인프런 워밍업 스터디 클럽 1기] FE 1주차 발자국
시작공부하며 개인적으로 중요하다 생각하는 부분과 복습할 내용, 헷갈리던 부분들을 정리해보았다. 프레임워크와 라이브러리에 의존적이던 나를 되돌아보는 시간이었던 것 같다. 정리Console 객체console.log(...data: any[]): void 로그console.error(...data: any[]): void 에러console.warn(...data: any[]): void 경고console.table(tabularData?: any, properties?: string[]): void 객체 데이터를 테이블로 표기console.time(label?: string): void, console.timeEnd(label?: string): void 사이에 코드를 입력하여 속도 측정 가능. label을 넣어서 무엇에 대한 측정인지 설명을 달 수 있음console.count(label?: string): void, console.countReset(label?: string): void 호출된 횟수 반환(특정 데이터가 몇 번 호출됐는지) 변수의 참조 범위(scope)자바스크립트는 블록 레벨 스코프 호이스팅var, let, const 셋 다 호이스팅 됨근데 var는 선언과 undefined로 할당되기 때문에 참조가 가능하고, let과 const는 선언만 되고 할당되지 않음 자바스크립트 타입원시타입은 콜스택에 저장(불변성을 가짐)참조 타입 값은 힙에 저장값에 대한 주소는 콜스택에 저장원시타입 : Boolean, String, Number, null, undefined, Symbol참조타입 : Object, Array, functuon, classes, …자바스크립트는 동적 타입이다어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당(및 재할당) 가능배열(Array)은 typeof를 쓰면 obejct로 나오기 때문에, Array.isArray(변수) 메서드를 통해 배열인지 확인할 수 있다배열이 object 타입이라고 나오는 것이 잘못된 것이 맞는데, 공식에서도 이것을 인지하고 있지만 당시에 이미 object로 처리하여 개발한 곳들이 너무 많아서, 혼란을 일으키지 않기 위해 그대로 object로 두기로 했다고 한다 자바스크립트 타입 변환String(변수), 변수.toString() 차이Number(변수), parseInt(변수) 차이자바스크립트가 자동으로 변수 타입을 변경하는 기준(ex. string 타입 + number 타입 ⇒ string 타입) Loopsfor … in : 객체의 속성을 따라 반복 ⇒ 객체 순회객체의 열거 가능한 속성들을 반복할 때 사용됩니다.객체의 속성들을 순회하며 각 속성의 이름(키)을 반환합니다.일반적으로 객체의 속성을 순회할 때 사용되며, 배열을 순회할 때는 사용하지 않는 것이 좋습니다.for … of : 반복 가능한 객체를 반복 ⇒ 배열 순회반복 가능한(iterable) 객체(배열, 문자열, 맵, 셋 등)의 요소들을 반복할 때 사용됩니다.각 요소의 값을 반환합니다.객체의 속성을 직접 열거하지 않고 요소들을 순회할 때 사용됩니다.forEach() : void 타입, for 루프는 await과 함께 작동하지만 얜 아님.map() : return 필요for 루프가 forEach보다 빠름 Window 객체**window 객체**브라우저에서 제공하는 객체브라우저의 창(window)을 나타냄. 브라우저 창에 대한 정보를 알 수 있고, 제어도 가능var 키워드를 통해 변수를 선언하면 window 객체의 프로퍼티가 됨let과 const는 window 객체 내부의 블록에서 선언된 것 → 전역 객체의 프로퍼티로 활용될 수 없음DOM(Document Object Model)메모리에 웹 페이지 문서 구조를 트리 구조로 표현해서 웹 브라우저가 HTML 페이지를 인식하게 해주는 객체 모델window.documentBOM(Browser Object Model)웹 브라우저와 상호작용하는 데 사용되는 객체 모델window.location, window.history, window.navigator 등속성window.innerWidth 속성브라우저 창의 내부 너비컨텐트 영역의 너비콘솔창/스크롤 바가 있는 경우에는 이를 제외한 영역의 너비window.outerWidth 속성브라우저 창의 외부 너비창의 테두리를 포함한 전체 외부 너비**window.scrollX 속성**x축 scroll의 시작점 좌표**window.scrollY 속성**y축 scroll의 시작점 좌표**window.location 속성**현재 창의 URL을 나타내는 객체**window.history 속성**브라우저의 세션 기록을 조작하고 탐색할 수 있는 객체window.location.href vs window.history.push()일반적인 이동은 history.push(), 이동과 함께 새로고침이 필요한 경우는 window.location.href 추천공통점 : 페이지 이동 location.href history.push() HTTP 요청 수행 O X 새로고침 O X Applcation 상태 유지(ex. 리액트의 state) X O 용도 현재 페이지의 URL 제어 브라우저의 탐색 히스토리 조작**window.navigator 속성**브라우저의 정보와 기능을 제공하는 객체주로 브라우저의 종류, 버전, 운영 체제, 언어 설정 등을 확인하고, 이에 따라 웹 애플리케이션을 조건부로 실행하는 데 사용함웹 페이지 빌드 과정(CRP, Critical Rendering Path)HTML → DOM TreeCSS → CSSOM Tree1, 2렌더 엔진이 문서를 읽어들여 파싱어떤 내용을 페이지에 렌더링할 지 결정비용이 크지 않은 작업DOM Tree + CSSOM 결합 → Render Tree브라우저가 DOM과 CSSOM을 결합화면에 보이는 모든 콘텐츠와 스타일 정보를 모두 포함하는 최종 렌더링 트리 출력Layout(reflow)브라우저가 페이지에 표시되는 각 요소의 크기와 위치를 계산Paint실제 화면에 그리기 DOM노드 타입Element, Attribute(deprecated), Text node, Comment node, Document itself, Doctype모든 타입의 노드에 적용 가능한 탐색 프로퍼티parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling요소 노드(Element 타입)에만 적용 가능한 탐색 프로퍼티parentElement, children, firstElementChild, lastElementChild, previousElementSibling, nextElementSibling자식 노드바로 아래의 자식 요소후손 노드중첩 관계에 있는 모든 요소자식 노드와 그 아래 자식 노드 모두 포함**element.innerHTML**html까지 출력됨**element.innerText****innerText**는 해당 요소의 텍스트 콘텐츠만을 반환HTML 태그를 고려하여 렌더링된 텍스트를 반환함(공백을 하나로 처리)CSS로 display: none; 또는 **visibility: hidden;**으로 숨겨진 요소의 텍스트는 반환하지 않음**innerText**는 보다 시각적으로 화면에 나타나는 텍스트만을 반환하며, 렌더링된 결과를 고려하여 처리됨**element.textContent****textContent**는 해당 요소의 모든 텍스트 콘텐츠를 포함하여 모든 하위 요소의 텍스트도 포함하여 반환HTML 태그를 무시하고 텍스트만을 고려함. 즉, HTML 구조를 고려하지 않고 텍스트만을 처리HTML 태그의 텍스트도 그대로 반환되며, 스크립트에서 태그를 제거할 필요가 없음**textContent**는 보다 일반적인 텍스트 콘텐츠를 반환하며, 숨겨진 요소의 텍스트도 포함될 수 있음**element.childNodes**text 노드가 포함된 NodeList 반환text 노드 : line break(엔터, 한 칸 띄움) 포함하여 반환배열 같아 보이지만, 유사 배열 객체인 컬렉션 타입컬렉션 타입 특징배열에서 사용하는 메서드를 사용할 수 없음배열의 반복 for … of, forEach() 사용 가능 (for … in 불가능)**element.children**children element nodes 반환text 노드도 포함 DOM 제어parentNode.appendChild(node) : node 추가parentNode.removeChild(node) : node 삭제parentNode.replaceChild(newNode, oldNode) : oldNode를 newNode로 대체 Event Listener & Event 객체이벤트를 등록하는 방법자바스크립트 코드에서 프로퍼티로 등록 (ex. onload)HTML 태그에 속성으로 등록 (ex. onClick)addEventListener 메서드 활용element.addEventListener(이벤트명, 실행할 함수명, 옵션)Event 객체event.clientY : 브라우저로부터의 마우스 이벤트가 발생한 거리 Y 좌표event.offsetY : 요소로부터의 마우스 이벤트가 발생한 거리 Y 좌표event.target : 실제 이벤트가 시작된 타겟 요소this 또는 event.currentTarget : 핸들러가 할당된 요소 Event 종류UI 이벤트load문서나 객체가 로드 완료 되었을 때 발생change객체의 내용이 변동되거나 focus를 잃었을 때 발생resize객체의 크기가 바뀌었을 때 발생scroll스크롤바를 조작할 때 발생error에러가 발생했을 때 발생키보드 이벤트keydown키를 눌렀을 때 발생keyup키를 눌렀다 뗐을 때 발생keypress사용자가 누른 키의 문자가 입력되었을 때 발생마우스 이벤트click객체를 클릭했을 때 발생dblclick객체를 더블클릭했을 때 발생mousedown마우스를 클릭했을 때 발생mouseout 마우스가 요소 밖으로 나갔을 때 발생 (자식 요소에 대해서도 이벤트를 처리함)mouseleave마우스가 요소 밖으로 나갔을 때 발생 (자식 요소에 대해서는 이벤트를 처리하지 않음)mouseover 마우스가 요소 위로 올려졌을 때 발생mousemove마우스가 움직였을 때 발생mouseup마우스에서 손을 뗐을 때 발생포커스 이벤트focus객체에 focus가 되었을 때 발생blur객체가 focus를 잃었을 때 발생폼 이벤트inputinput, textarea 요소 값이 변경되었을 때 발생changeselect box, check box, radio button의 상태가 변경되었을 때 발생select텍스트를 선택했을 때 발생reset리셋 버튼을 눌렀을 때 발생submit사용자가 버튼키 등을 활용해 폼을 전송할 때 발생cut/copy/paste사용자가 폼 필드의 콘텐츠를 잘라내기/복사/붙여넣기했을 때 발생동일한 요소에 이벤트가 적용되어 있을 때, 이벤트 발생 순서keydown → keypress → keyupmousedown → mouseup → click이벤트의 3단계 흐름 캡처링 단계 : 이벤트가 하위 요소로 전파되는 단계타깃 단계 : 이벤트가 실제 타깃 요소에 전달되는 단계버블링 단계 : 이벤트가 상위 요소로 전파되는 단계 Event Bubbling이벤트 버블링이란, 가장 깊게 중첩된 요소에 이벤트가 발생했을 때 이벤트가 위로(bubble up) 전달 되는 것을 의미함타깃 이벤트에서 시작해서 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생3번 요소, 2번 요소, 1번 요소에 이벤트 핸들러가 있다면, 3번 요소 핸들러 → 2번 요소 핸들러 → 1번 요소 핸들러 순으로 실행됨event.stopPropagation() 메서드를 활용하여 버블링을 중단하면 부모 요소(상위 요소)의 핸들러는 호출되지 않음 Event Capturing이벤트 캡처링이란, 제일 상단에 있는 요소에서 아래로 이벤트가 내려오는 것을 의미함addEventListener() 메서드의 두 번째 인수에 { capture : true } 옵션을 넣어주면 캡처링 과정을 확인할 수 있음 이벤트 위임 (Event Delegation)하위 요소의 이벤트를 상위 요소에 위임하는 것을 의미. 즉, 하위 요소의 이벤트를 상위에서 제어함동일한 기능을 가진 요소임에도, 추후에 코드를 통해 추가된 요소일 경우 이벤트 리스너를 다시 등록해줘야 하는 번거로움이 있음 → 이벤트 위임을 활용하여 해결할 수 있음하지만 주의할 점이 한 가지 있음. 상위 요소에 등록된 이벤트 핸들러가 하위 요소에 있는 요소에 대해서만 동작하도록 설정해야함. 이렇게 하지 않으면 상위 요소의 아무 곳이나 클릭했을 때도 이벤트가 발생할 수 있음하위 요소가 버튼이라고 쳤을 때, 이벤트 핸들러에서 클릭된 요소가 버튼인지 확인하는 로직이 필요함 회고역시 기본기가 가장 중요하다는 것을 다시 느꼈다. React를 쓰며 state로 인해 자동으로 업데이트 되는 화면에 익숙해졌던 것 같다. 프레임워크와 라이브러리에 대한 의존 없이도 스스로 구현해낼 수 있도록 연습하는 것이 좋겠다.
프론트엔드
・
인프런워밍업스터디클럽
・
FE
・
1기
・
발자국