- DOM : Document Object Model로 JS가 Document(HTML문서)를 알아 볼 수 있는 Object 형태로 Modeling(파싱, 해석) 한 결과물, 브라우저에 내장된 API 중 하나(이 API를 통해 DOM요소에 접근해 제어하면 브라우저의 많은 것을 컨트롤이 가능함), DOM은 계층 구조로 구성 되어 있어 부모자식 관계로 구성(호출 가능), DOM은 무조건!!! 브라우저 환경에서만 돌아간다(브라우저에 내장된 API), DOM은 node를 갖고 각각 node들은 속성과 메소드를 가짐
- API : 주문 시 메뉴판과 같은 역할로 다른 시스템에서 데이터나 서비스를 요청 할 때 ★★★다른 시스템에서 제공하는 기능을 사용할 수 있도록 ★★★시스템과 사용자 간의 인터페이스 역할을 함(중간자 역할)
- 브라우저는 DOM API를 제공함으로 DOM 객체에 접근 할 수 있도록 도와주는 역할을 함. => DOM을 통해 HTML내용을 ★★★접근 할 수 있고 제어 할 수 있다★★★ ex) 현재 위치의 날씨를 확인 하려면 날씨 앱에서 제공하는 날씨 서비스 API를 호출 해 정보를 받아옴
- DOM 관련 예) documennt.getElementById("id_name").innerHTML = 'Hello' , 여기서 나오는 동사는 메소드라 생각하고 명사는 속성이라 생각하기!(getElementById가 메소드 / innerHTML가 속성) / li태그들을 가져오고 싶을 때에는 getElementsByTagName('li')[으로 s가 꼭 붙어야 오류가 나질 않음(예제 li는 DOM 객체에 상에 여러 개 있으므로) , document.querySelector('footer').setAttribute('style', 'background-color : red;'); => footer부분의 스타일을 바꿔라~ , document.getElementsByTageName('h1')[0].innerText = 'abcdef' => h1태그의 제일 상단에 있는 것을 바꿔라
- etc ) 선택자 : id=" "와 같이 특정 태그를 선택하기 위한 요소를 선택자라고 함. / 특정 선택자를 가져올 때는 querySelector를 제일 많이 사용 : document.querySelector('id/class/tag') - #id_name / .class_name / tag(앞에 아무것도 쓰지 않으면 태그 이름을 의미하는 것!), .children - 자식 노드 접근 / .parentElement(=parentNode) - 부모 노드 접근
- 클라이언트 = 브라우저 = 사용자 (즉 우리가 크롬을 통해 클라이언트 역할)
- 웹 페이지가 보여지는 과정 : 1. Client가 Server에게 요청(Request) -> 서버에서 응답을 준다(response) -> Client가 이응답을 수신하는데 응답의 형태가 HTML문서임(JS가 이해할 수 없음) -> 브라우저 내부의 렌더링 엔진을 통해 이 HTML문서를 해석함(JS가 알아들을 수 있도록!!)
- 2. 렌더링을 마치면 JS가 해석한 내용을 토대로 트리형태의 DOM Tree를 구성함! -> CSS도 CSSON Tree가 만들어지는데 이 두개를 묶어 Render Tree를 구성한다.
- 3. 화면에 그림을 그리기 위한 레이아웃을 계산 한 뒤 페인팅 과정으로 Client에게 제공
- 클래스(class) : 클래스 문법은 ES6에서야 도입되었음(다른 언어들을 사용하던 개발자들이 JS로 넘오면서 클래스 처럼 사용하게 되면서 개발이 됨), 설계도(ex) 책상을 만들기 위한 설계도)로 이 설계도를 통해 특징(인스턴스)이 무엇인지 알 수 있음
- 인스턴스(instance) : 클래스를 기반으로 만들어진 실제 사물(ex) 책상), 설계도에서 그려진 속성과 메소드를 가짐
=>class에는 constructor(생성자 - 매개변수 값에 해당 클래스가 가져야 할 필수 값(property)을 넣어줘야 함)가 필수 & 메소드를 넣을 수 있음 (클래스는 객체를 정확하고 빠르게 많이 만들 수 있기에 사용)
- Getters / Setters : 모든 객체 지향 프로그래밍 언어가 가진 기본적 개념, 생성자에서 property(필수 입력 값)를 정의 하는데 이 property에 접근하고 세팅하기 위해 지원함,
- 1) get은 외부에서 해당 객체 property를 요구할 때 내부 값을 반환해서 출력해주는 역할(retrun이 필요하다!) ex) console.log(car1.modelName) - car1의 modelName을 get해서 출력해주세요.
- 2) set은 value를 생성자의 property에 set해주는 것이므로 value라는 매개변수가 들어옴 -> 해당 property를 내부적으로 검증 후 세팅할 수 있도록 제약 조건을 만드는 것!
- Getters / Setters 사용시 주의!! : 객체의 property값과 변수이름을 같게 하면 생성자의 검증 메소드인 set이 무한루프가 일어남(콜스택에 실행컨텍스트가 계속 쌓여 사이즈가 커져 오류 : Maxinun call stack size exceeded) 따라서 get/set이 나오는 생성자는 모든 this에 접근하는 property이름을 _(underscore)를 사용해 선언
=>은밀하고 감춰야 할때(이 인스턴스 내부에서만 사용) _(underscore)를 붙이기!(getters / setters 사용 약속!)
* 위에 만든 Car Class에 요구사항 붙이기(각 인스턴스를 가져오고 세팅하는 메서드 & 이걸로 set해서 get하는 로직까지)
=> 위의 유효성 검사는 예시임 value.length는 문자열만 가능하기에 거기에 다른 숫자가 들어오게 된다면 undefined가 들어오게 됨 따라서 modelYear 검증 부분에 if(value.length !== 4)부분이 먼저 나오면 무조건 이 조건을 만족함(undefined.length는 4가 아니기 때문에) 그래서 string 타입인지를 먼저 비교 하고 나서 4자리인지 검사해야 함(조건에 따라 다르게 설정하기) => String(value).length로 비교 or value.toString().length로 명시적 형 변환으로 비교도 가능하긴 함.
※ 주의 : 숫자는 length를 쓸 수 없다! 사용하기 위해선 String으로 명시적 형변환을 통해 문자열로 바꾼 후 사용이 가능함!! (사용 시 undefined로 출력)
- 상속(Inheritance) : 클래스를 유산으로 내려주는 주요 기능(부모가 가진 형과 질을 내려주는 것!) 부모 <-> 자식, 상속받는 자식 클래스는 기본적으로 생성자를 생성 하지 않아도 됨. 상속받을 자식 클래스에게 꼭! extends 부모클래스명을 추가!
=> 메소드를 재정의 행위는 오버라이딩임. (부모로 부터 내려받은 메소드를 재정의 해서 braks!가 출력이 됨)
* 상속 예시 2)
=> 위처럼 자식 클래스의 생성자를 재정의(오버라이딩) 하려면 생성자를 꼭 다시 선언하고 내부에 super로 부모것을 가져오는 부분도 적어줘야 함! - 부모와 자식의 생성자가 다르기 때문에 sync를 맞추기 위해 적어주는 것임
- Static Method(정적 메소드) : 내부 메소드가 static임, 굳이 인스턴스화 시킬 필요가 없는(객체를 만들 필요가 없을 경우) 경우에 주로 사용함.
=> 계산기 경우 new로 객체를 만들 필요가 없으니 바로 접근해서 호출하려 한다! 이때 정적 메소드가 사용됨.
- Closure : 함수와 그 함수가 선언된 LE(Lexical Environment)와의 조합, 외부함수(outer())보다 중첩함수(innerFunc())가 더 오래유지 될 때! 중첩함수는 이미 생명주기가 종료된 외부 함수의 변수를 ★★★여전히★★★ 참조 할 수 있다.
=> outer()함수를 실행 해 innerFunc에 담는다(outer()의 return 부분을 innerFunc에 넣음), InnerFunc 선언시점 후로 outer()의 실행컨텍스트는 콜스택에서 popup되어서 종료(사라짐) but!!! 클로저로 인해서 outer()가 콜스택에서 사라졌음에도 innerFunc는 outer()의 x를 여전히 가져와 출력할 수 있다!! (여전히 참조하고 있기 때문에 Garbage Collector가 이 x를 수거해 가지 않았음)
- Garbage Collector : 참조카운트 0인 값들을 수거! but 참조하고 있는 값들은 가져가지 않음(안쓰는 애들만 가져감)
=> 여기서의 innerFunc에서의 x는 내부에 없음 따라서 외부 환경(outer)으로 시선을 돌려 outerFunc에 있는 10을 가져옴(outer는 이 innerFunc가 실행 될 때의 당시 변수 정보인 LE이다 - 함수 선언!! 당시의 외부 변수등의 정보)
- Lexical Scope : JS엔진은 함수를 ★★★어디서 호출★★★했는 지가 아닌 ★★★어디에 정의★★★ 했는 지에 따라서 스코프(상위 스코프)를 결정한다!!!
- outer : 실행컨텍스트에 있는 outer는 외부 LE에 대한 참조값이다!, outer는 함수 선언(정의)되는 시점에 결정이 됨!!!
=> 스코프 접근 불가 ex) outerFunc내부에 innerFunc가 호출되고 있음에도 불구하고 Lexical Scope를 따르는 프로그래밍 언어이기에 innerFunc에서는 outerFunc의 x에 접근 할수가 없다(★서로 별도의 스코프 가짐★) 따라서 x는 1이 출력
- 클로저 복습(매우매우 중요!) : 상태를 안전하게 은닉하면서 변경하고 유지하기 위해 사용
=> 변수가 은닉 되지 않았기에 중간에 num = 100; 이렇게 넣어버리면 바뀌어버리는 치명적인 단점
* 보완해보기 : 1. 카운트 상태(num 변수 값)는 increase 호출 전까지 변경되면 안된다(중간에 바껴버리면 치명적) 2. 카운트 상태는 오직 increase 함수만이 변경해야 한다! 3. 결국 전역변수 num이 문제
-> if) 지역변수로 넣는다면? 문제가 생김 : increase()가 호출될 때마다 num이 초기화 되어서 1만 출력이 됨.
-> 클로저 적용해보기!
=> 1. 코드 실행 시, '즉시 실행 함수'가 호출됨(increase의 function() 내부) -> 이 함수가 반환이 되어 increase에 할당!
2. increase 변수에 할당된 함수는 자신이 정의된 위치에 의해 결정된 상위 스코프인 즉시 실행 함수의 LE를 기억하는 클로저다 -> increase는 let num = 0; 을 기억함.
3. 즉시 실행 함수는 소멸(콜스택에서 popup됨) -> but num은 클로저로 인해 남아있음(증가가 실행이 됨)
※결론 : num은 초기화되지 않고 외부에서 접근할 수없는 은닉된 값 & increase에서만 num 변경 가능
숙제) 숫자맞추기
구현 1. 남아있는 숫자를 보여줄 수 있게 아래의 = 이후 작성
=> 총 10번의 기회이고 numGuesses의 초기값이 1이므로 11을 빼야 정상 작동(0이라면 10을 빼야함)
구현 2. 유저에게 메시지를 보여줄 수 있도록 아래의 영역 구현
=> 사용자가 정답을 맞추기 위해 범위 내의 숫자를 입력하면 기회가 남아있는 경우에 compareGuess 함수로 정답의 수와 비교를 해서 거기에 맞는 displayMessage(출력할message)함수를 실행하므로 이것을 $guessingResult부분에 출력을 하면 됨(여기서 빽틱으로 h1태그를 감싸면 자동으로 css에서 h1태그를 대상으로 지정한 css를 적용해서 출력하게 됨.)
구현 3. 유저가 원의 크기로 정답을 유추하기 쉽게 showCircle함수 이용해 구현하기, 함수 작업이 끝나면 해당 div에 원의 이름 입력하기.
=>위에서 게임을 시작할 때, makeAnswerCircle(randomNumber, "answer")을 넣어줘서 실행 하므로 정답의 수의 크기에 원을 그려줌(그려주는 위치는 $answerCircleArea부분에) 그리고 난 후에 이 원안에 answer이름을 넣어줌.
=>이 원은 입력을 하게 되면 checkGuess함수가 실행되면서 도전 기회가 아직 남아있을 때 기존의 원을 지우고 추측값을 비교하는 compareGuess함수를 실행 해 해당 추측값의 원 크기를 그려줌 - makeGuess(guess, "guess") (함수안에 원 이름의 변수를 생성해서 넣어도 되고 위에 make처럼 인자를 받아 그걸로 변수 이름을 넣어도 된다.
'JS' 카테고리의 다른 글
| JS 내용 정리 (1) | 2023.06.03 |
|---|---|
| JS 메소드 (4) | 2023.05.30 |
| JS 4주차 개념 정리 (0) | 2023.05.25 |
| JS 3주차 개념 정리 (0) | 2023.05.23 |
| 개발일지(2023.05.22) (0) | 2023.05.22 |