2024.06.11 프로그래머스 - JS 알아보기 2
JS 알아보기 2
Flow control(제어흐름)의 이해
flow control 예시
하나의 버튼을 두고 해당 버튼이 동작하는 flow를 구상해보았을 때의 flow는
- 버튼이 클린된다.
- 버튼 옆의 check box가 활성화(checked) 되어 있다면,
- 버튼이 빨간색이 되고,
- 버튼옆의 check box가 비활성화(Unchecked) 되어 있다면
- 버튼이 파란색이 된다.
- flow control은 위와 같이 개별 명령문, 명령 또는 함수줄이 실행되거나 평가되는 순서에 따라 제어 된다.
- 제어흐름의 종류
goto : 다른 구문에서 시작하는 제어흐름- choice : 일부 조건이 충족된 경우에만 일련의 명령문 실행
- if-else, switch
- loop : 어떤 조건이 충족 될 때 까지 일련의 명령문을 0회 이상 반복 실행
- collection Loop, General Loop
- continue : 현재 실행 구문에서 떨어진 한 구문의 집합을 실행
- Loop continuation
- break : 프로그램 실행을 중단
- Loop early exit, 함수 실행 정지
표현식과 문의 개념
- 표현식
- 값으로 이행되는 임의의 유효한 코드 단위
- 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조
- 값으로 평가 될 수 있는 문은 모두 표현식이다.
- 문 (statement)
- 프로그램을 구성하는 기본단위, 최소 실행 단위
- ⇒ 명령문, 선언문, 할당문, 제어문, 블럭문 등
- 블럭문 : 한쌍의 중괄호 (
{}
) 로 묶은 명령 실행 줄
- 프로그램을 구성하는 기본단위, 최소 실행 단위
조건문
- if … else, switch
- if…else 문
- 논리조건이 참인 경우 if 블럭문 실행,
논리조건이 거짓인 경우 else 블럭문 실행
1 2 3 4 5 6 7
const a = false if (a) { console.log("참") } else { console.log("거짓") } // 실행 결과 : "거짓"
- switch 문
라벨이 포함된 case 문을 작성하여, 해당 case 속하는 논리의 경우 해당되는 case의 명령문을 실행 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
const text = "a" switch (a) { case "a" : { console.log("A") } case "b" : { console.log("B") } default : { console.log("영어가 아님") } } // 실행 결과 : "A"
반복문
- conditional Loop
- 일부 조건이 변경 될 때 까지 루프를 반복 하는 구조
- 시작할 때 조건을 평가하는 유형 : 본문 생략 가능
- 마지막에 조건을 평가하는 타입 : 본문은 항상 한 번 이상 실행 됨
시작할 때 조건이 평가되는 유형 : while 문
1 2 3 4
let num = 0; while (num === 3) { num++ }
마지막에 조건을 평가하는 타입 : do-while 문
1 2 3 4
let num = 0; do { num++ } while (num === 3)
- 조건문에 대해 언젠가 false 확실히 처리되도록 작성해야 한다. (무한루프 예방)
- 일부 조건이 변경 될 때 까지 루프를 반복 하는 구조
- for Loop
특정 부분의 코드가 반복적으로 수행 될 수 있도록 한다.
1 2 3 4 5 6 7 8
for (let i = 0; i < 5; i++) { console.log(i) } // 0 // 1 // 2 // 3 // 4
break 또는 continue 문을 사용하여, 반복에 대한 제어 흐름을 컨트롤 할 수 있다.
- collection Loop
- for…in, for…of
- for…in : 객체의 열거 속성을 통해 지정된 변수를 반복한다.
- 객체에서 문자열로 key가 지정된 모든 열거 가능한 속성에 대한 반복
- for…of : 반복가능한 객체(iterable) (Array)
- break 문
- 가장 가까운 loop에 대한 흐름을 중지하고 다음 문으로 넘어가는 역할
- continue 문
- 현재 실행 구문에서 떨어진 한 구문의 집합을 실행
- 실질적으로 다음 Loop를 실행 시키는 역할 이다.
- for : 증감문으로 이동
- while : 조건문으로 이동
예외 처리 하기
예외 상황
- 런타임 때 발생 할 수 있는 의도치 않은 상황
- 예외의 원인
- 코드레벨
- 하드웨어 (디바이스)
- 라이브러리 손상
- 사용자 입력 실수 등
- JS의 예외의 종류
- ECMAScript Error : JS언어에서 발생하는 Error Type
- Range Error
- Reference Error
- Syntax Error
- Type Error
- DOMException : Web API 레벨에서 발생하는 Error Type
- NetworkError
- AbortError
- TimeoutError
- 그 외의 예외
- Error 객체를 사용하여 개발자가 직접 에러를 정의내리고 사용한다.
- ECMAScript Error : JS언어에서 발생하는 Error Type
throw 와 Error 객체
- throw 문
- 예외를 발생 시킬 때 사용
- catch block 에서 에러 객체 핸들링
- throw문 이후의 명령문은 실행 되지 않는다.
- Error 객체
- 사용자가 Error 객체를 정의하여 사용할 수 있다.
- new Error(”에러 내용”)
- Error.message
- Error.name
- 사용자가 Error 객체를 정의하여 사용할 수 있다.
try…catch 문
try 문 내의 흐름에서 예외가 발생하면, catch 블록에서 발생한 예외를 받아서 처리 및 그에 따른 수행 문을 실행
- 에러가 throw 되면 ,
콜스택
을 확인하여 핸들링 하고 있는 catch문이 있는 스택에서 처리 - catch 문에서 에러를 처리하게 되면, error 는 상위 흐름까지 역류하지 않는다. (버블링)
- catch 문에서 에러를 처리하지 못해 최상위 스코프 까지 error 가 올라가면 프로그램 구동자체가 멈추는 에러가 발생한다.
- try-catch문에 finally 문을 추가하여, 무조건 실행되는 블록을 구성 할 수 있다.
객체란 (object)
- 속성을 가진 독립적인 집합 객체
- JS는 객체 기반의 프로그래밍 언어
- 속성
- 키와 값 (key- value) 사이의 연결관계
- 객체에 속해 있는 함수를
method
라고 부른다.
- 객체 생성 방법
리터럴표기법
1
const foo = {name : "able" }
- 생성자 함수
- 생성자 함수를 사용하여 새로운 인스턴스로 객체를 생성하는 방법
- new 키워드를 통해 생성한다.
- this 키워드로 속성을 정의하여 생성될 인스턴스를 가리키게 해둔다.
- 함수 선언문의 this로 작성해야, 호출되는 this가 호출하는 인스턴스를 가리키게 된다.
1 2 3 4 5 6
function Car(width, height){ this.width : width this.height : height } const truck = new Car(2500, 1200)
Object.create
1 2 3 4 5 6 7 8 9
const Car = { name : "Car", width : 2500, height : 1200, getName : function () {return this.name} } const Truck = Object.create(Car) Truck.name = "Truck"
- Object 객체의 인스턴스 method
- hasOwnProperty()
- isPrototypeOf()
- propertyIsEnumerable()
- toLocaleString()
- toString()
- valueOf()
- Object 객체의 정적 method
- assign : 객체 복사
- create : 신규 생성
- freeze, preventExtension, seal : 객체 고정
- isExtensible, isFrozen, isSealed : 객체 상태 확인
- entries, fromEntries : 객체 배열로 반환
- getOwnPropertyOf, setOwnPropertyOf : 객체 prototype
- 객체의 속성 나열
- for…in : 객체의 프로토타입 속성 까지 열거
- Object.keys(객체) : 객체 자신의 열거 가능한 속성이름을 배열로 반환
- Object.getOwnPropertyNames(객체) : 객체 자신만의 모든 속성을 배열로 반환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const Person = { age : 20, gender : "male" } function Child(name){ this.name = name } const danny = new Child("danny") Object.keys(danny) // ["name"] Object.getOwnPropertyNames // ["name"] for (key in danny) { console.log(key) } // ["name", "age", "gender"]
- 객체의 비교
- 객체 속성과 값이 같더라도, 참조 값이 다르기 때문에, 무조건 다른 객체 끼리는 false
- 자신 과의 비교에서만 true가 된다.
- 객체의 복사
- 얕은 복사
- 복사된 객체의 속성 중 하나라도 같은 참조를 하고 있다면 얕은 복사
- 객체의 속성중 참조 타입이 없는 경우에만 얕은 복사 방법 권장
- Object.assign({}, 복사할 객체)
- spread연산자 ({…복사할 객체})
- 깊은 복사
- 복사된 객체의 속성 중 하나라도 같은 참조가 없다면 깊은 복사
- 재귀함수를 이용한 복사 (라이브러리 : lodash - cloneDeep)
- JSON.parse(JSON.stringify(객체)) (객체 → 문자열 변환 = 참조 제거 → 객체로 변환)
- 얕은 복사
빌트인 객체
- Object, String, Number, Function, Array, RegExp, Date, Math
- Number 객체
- 숫자를 표현하고 다룰 때 사용하는 원시래퍼 객체
- static 속성
- MAX_VALUE, MIN_VALUE, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER
- 메소드
- isNaN, isFinite, isInteger
- parseInt, parseFloat
- Math 객체
- 수학적인 상수와 함수를 위한 속성과 method를 가진 내장 빌트인 객체
- static 속성
- PI, E ..
- method
- abs, pow, sqrt
- ceil, floor, round
- max,min
- random 등
- Date 객체
- 1970년 1월 1일 UTC 자정과의 시간차이를 밀리초 단위로 나타낸것
- UTC = GMT로도 불린다.
- ISO8601
- YYYY-MM-SSThh:mm:ssZ
- T는 상호합의간 생략가능
- UTC 날짜라는 의미로 Z를 표현한다.
- method
- now()
- parse()
- UTC()
- toLocalString() (Object method를 상속받기 때문에 사용가능)
- 인스턴스 메서드
- getFullYear, getMonth, getDate, getDay
- getHours, getMinutes, getSeconds, getMilliseconds
- getTimezonOffset : UTC와 현지시간대의 차이를 분단위로 갖고 온다.
- String 객체
- 인스턴스 메서드
- at, charAt..
- indexOf, lastindexOf, search
- includes, startsWith, endWith
- match, matchAll
- localeCompare
- toLocaleLowerCase, toLocaleUpperCase, toString
- replace, reaplceAll
- padENd, padStart, repeat
- concat
- slice, substring, split
- trim, trimStart, trimEnd
- 인스턴스 메서드
정규 표현식 (Regular Expression)
- 문자열에서 특정 문자 조합을 찾기 위한 패턴
- /패턴/플래그
- 정규표현식 생성
- 리터럴 표기법
- JS가 평가할 때, 정규표현식을 컴파일 한다.
- RegExp 객체
- 런타임 때 컴파일 된다.
- 패턴이 변할 가능성이 있거나, 알수없는 데이터에 대해 구현하는경우 사용
- new RegExp
- 리터럴 표기법
- 생성자 함수 : RegExp
- static 속성
- lastIndex
- 인스턴스
- 속성
- 적용된 flag 반환 : flags
- 적용된 flag 여부 반환
d
otAll,g
lobal,i
gnore,m
ultiline,s
ource, sticky
,u
nicode
- method
- compile, exec, text, toString
- String 객체와 같이 사용하는 method
- match, matchAll
- search
- replace, replaceAll
- split
- 속성
Collection
- 데이터 항목들의 그룹을 의미
- list, set, tree, graph
- JS의 collection
- indexed collections
- key collections
indexed collections
- index 값을 기준으로 정렬되어 있는 데이터 집합
- Array, typedArray 포함
- index로 배열내의 값 참조
Array 객체
- 이름과 인덱스로 참조되어 정렬된 값들의 집합
- 0개 이상의 식 목록
- 길이가 고정되어 있지 않다.
- 각 요소의 data Type은 고정되어 있지 않다.
- 모든 요소는 필수 값이 아니다.
- 생성 방법
- 배열 리터럴 : []
- Array 객체 생성자
- 특징
- 0부터 인덱스 시작
- index로 문자열을 사용할 수 없고 무조건
정수
만 사용가능 - index로 참조하지 않은 값은 객체의 속성으로 저장됨
- 배열의 길이 : 마지막 index + 1값
- 길이지정 가능
- 원래 길이보다 작게 지정하면, 배열이 잘림
- 원래 길이보다 크게 지정하면, 배열의 길이가 늘어남
- 길이지정 가능
- 배열의 반복 처리
- for문 또는 forEach문
- static method
- from, isArray, of
- 생성자
- Array.prototype
- 인스턴스 속성 : length
- method
- get, set, set
- method
- 요소 check method
- 접근 : at
- 찾기 : indexOf, lastIndexOf
- 포함 여부 : includes
- 순회
- 순회 확인 : forEach
- 순회 판별 : every, some
- 순회 찾기 : find, findIndex
- 요소 조작 method
- 추가 : push, unshift
- 제거 : pop, shift
- 배열 합치기 : concat
- 추가하기 : fill
- 분리 : slice, splice
- 요소 변경 : copyWithin, flat
- 배열 재배치 : reverse
- 순회 재배치 : sort
keybased collections
- Key 값을 기준으로 정렬되어 있는 데이터 집합
- Map, Set
- 키와 값을 매핑하여 저장
Map
- key-value를 매핑 시켜서 저장
- key는 유니크하다.
저장된 순서대로 요소를 반복적으로 접근 할 수 있다.
- Map 과 Object 의 차이점
| 비교 | Object | Map | | ————————- | ———————————– | ———————————— | | 속성의 데이터 타입 | string, Symbol 타입만 가능 | 모든 값을 key로 활용가능 | | default 속성과의 충돌 | Object prototype의 기본 속성과 | | 동일한 key를 생성 시 충돌 | Map은 기본적으로 가진 속성이 없어서 | | 기본 속성들과 충돌 없음 | | 객체의 크기 | 수동으로 추적 | size 인스턴스 속성으로 얻을 수 있다. | | 순서보장 | Object는 순서보장이 안된다 | Map은 추가된 순서대로 순서 보장 | | iterable 여부 | Object는 iterable이 아니다. | Map은 Iterable이다 | | 퍼포먼스 | key-value의 빈번한 추가 제거에는 | | 퍼포먼스가 좋지 않다. | key-value 의 빈번한 추가 제거에는 | | Map이 퍼포먼스가 좋다. | | 직렬화 구문분석 제공 여부 | JSON.stringufy, JSON.parse | Map은 직렬화 구문분석이 없음 | | (커스텀은 가능) |
- Map 의 method
- 체크 (get) : get, has
- 변경 (set) : clear, delete, set
- 순환관련 : keys, values, entries, forEach
WeakMap
- 키에 대한 강력한 참조를 생성하지 않는 key-value 쌍의모음
- key로 Object만 허용
- 객체의 정보를 노출하지 않는다.
- 객체의 정보를 비노출 하는 특징 활용
- 객체에 사적인 정보 저장
- 상세 구현 내용 은닉
Set
- 중복된 값을 허용하지 않는다.
- 값이 같으니 검사를 수행한다.
- 배열을 인자로 받을 수 있다.
- 중복된 요소는 제거 된다.
- 모든 값들의 집합
- 입력된 순서에 따라 저장된 요소를 반복처리 할 수 있다.
- 특정 값은 Set 내에서 하나만 존재한다.
- NaN
- 배열 ⇒ Set, Set ⇒ 배열로 전환 가능하다.
- method
- 요소 체크 : has
- 요소 변경 : clear, delete, add
WeakSet
- 객체 컬렉션 (object만 허용)
- 약한 참조를 가진다.
- method
- 요소 체크 : has
- 요소 변경 : delete, add
- 순환관련 method 없음.
JSON 객체
- Javascript Object Notation
- 인터넷에서 자료를 주고 받을 때 자료를 표현하는 방법 중 하나
- 사람이 읽을 수 있는 텍스트를 사용하는 open Standard
- 직렬화 : Object ⇒ 문자열로 변환하는 것 JSON.stringify
- 역직렬화 : 문자열 ⇒ Object로 변환하는 것 JSON.parse
국제화 : Intl 객체
- 각 언어에 맞는 문자, 숫자, 시간, 날짜비교를 제공하는 국제화 API를 위한 namespace
DateTimeFormat 생성자 함수
- 언어에 맞는 날짜, 시간 서식을 적용하기 위한 객체
- 생성자 함수 : Intl.DateTimeFormat
- method
- 포맷 결과 : format, formatRange
- 포맷 결과를 각 단위별로 분해하여 배열화 : formatToParts, formatRangeToParts
1 2 3 4 5 6 7 8 9 10 11 12 13
const dateTimeFormatKo = new Intl.DateTimeFormat("ko"); console.log(dateTimeFormatKo.format()) // 2024. 6. 11. console.log(dateTimeFormatKo.formatToParts()) /* [ {type: 'year', value: '2024'}, {type: 'literal', value: '. '}, {type: 'month', value: '6'}, {type: 'literal', value: '. '}, {type: 'day', value: '11'}, {type: 'literal', value: '.'} ] */
NumberFormat 생성자 함수
- 언어에 맞는 숫자를 formatting 할 때 사용하는 함수
1
2
3
4
5
6
const numberFormatKo = new Intl.NumberFormat('ko', {
style : 'currency',
currency : 'KRW'
})
numberFormatKo.format(125000) // '₩125,000'
프로토타입과 생성자 함수
OOP : 객체 지향 프로그래밍
- 객체 : 현실의 개념을
추상화
하여 정의- 상태 → this
- 식별자 → 속성
- 어떤 행동을 한다 → method
- 인스턴스 객체
- 개념의 일원으로써 생성된 객체
- 객체 지향 프로그래밍 : 객체 라는 기본단위로 나누고, 이들의 상호작용으로 서술하는 방식
- JS는 프로토타입 기반 객체지향 언어
프로토타입 객체
- 객체의 인스턴스를 만드는 부모 객체 개념
- JS의 모든 객체는 부모 객체인 프로토타입 객체와 연결되어있음
- 부모 객체의 속성과 메서드를 상속받아 사용 가능
__proto__
접근자 속성으로 객체의 프로토타입 객체에 접근- [Prototype] 은 상속을 위해 사용한다
- constructor 객체 : 자기 자신을 생성한 객체에 대한 참조
프로토타입 chain 상속
- 객체의 속성 참조시, 속성이 없는 경우, 프로토타입 체인 동작
- [[Prototype]] 을 통해서 부모 객체 탐색
- 모든 객체의 부모는 Object.prototype
- 만약 마지막 부모객체 에서까지 속성을 찾지 못할 경우, undefined로 반환
- 상속
- prototype 객체 속성과 메서드 정의 시, 인스턴스 객체에서 부모 메서드와 속성을 참조
- 객체와 프로토타입에 동일한 이름의 속성이나 메서드가 있는경우
- 객체의 속성이 먼저 참조 된다.
- property shadowing : 프로토타입 속성이 가려지는 현상
- method overriding : 프로토타입 메서드가 가려지는 현상
- 객체의 속성이 먼저 참조 된다.
class 문법
- ES6 에 추가된 class 문법
- 기존 프로토타입 기반 상속 매커니즘의 추상화
- symantic sugar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// class class Person { constructor(name, age) { this.name = name this.age = age } get upperCaseName() { return this.name.toLocalUpperCase() } set plusYear(age) { this.age += age } static legCount() { return 2; } } Person.legCount(); // static method const James = new Person("James" , 35) James.upperCaseName(); // getter James.plusYear = 5; // setter console.log(James.upperCaseName, James.age) // "JAMES" 40
constructor
- 인스턴스를 생성하고 클래스 필드를 초기화하기 위한 약속된 특수 메서드
- 인스턴스가 생성될 때 호출되는 메서드
- 생략도 가능하다
- 인스턴스를 생성하고 클래스 필드를 초기화하기 위한 약속된 특수 메서드
인스턴스 method
- 클래스 내에 존재하는 method
- method 내에서 클래스를 this로 접근 가능
- 클래스의 인스턴스 속성에도 접근 가능
정적 메서드
(static method)- 클래스의 인스턴스를 생성하지 않아도 호출할 수 있는 method를 정의할 때 사용
- static 키워드를 사용한 내부 인스턴스 method
- utility의 성격을 가진 method를 정의할 때 사용
인스턴스 속성
- 클래스 내부에 캡슐화 된 변수 == 멤버 변수
- this에 추가한 속성
- 인스턴스 속성은 this에 바인딩 필요
- 인스턴스 속성의 초기화는 constructor에서 수행
getter
- 특정 인스턴스 속성을 조회하는 method
- method 이름 앞에 get 키워드 사용
- getter는 무조건 값을 반환
- 속성처럼 참조하는 형식으로 사용한다. (호출 X)
setter
- 특정 인스턴스 속성에 값을 할당하여 조작하는 method
- method의 이름 앞에 set 키워드를 사용
- 호출 형식이 아닌, 할당문의 형식으로 사용
클래스 상속
- 코드의 재사용 관점에서 상속이 필요
- extends 와 super 키워드를 통해 class에서 상속을 구현
extends
- 부모 클래스를 상속받는 자식클래스를 정의할 때 사용
- class 자식 extends 부모
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Car{
constructor(name) {
this.name = name
}
}
class Suv extends Car {
constructor(name) {
super(name)
}
action () {
return this.name + "Going Home"
}
}
const sportage = new Sub("sportage");
sportage.name; // "sportage"
sportage.action // "sportage Goting Home"
super
키워드를 자식 class의 constructor에 호출하여, 부모 클래의 생성자를 호출 한다.- 부모 클래스의 인스턴스 속성을 바인딩
- 자식클래스의 생성자가 super로 호출된 부모 class의 this에 접근하고 수정 가능
- 부모 클래스와 공통된 변수를 선언, 초기화시 간결하게 처리 가능
- 상속받는 자식 클래스는 super 키워드 이후에 this 초기화 가능
- super.method()를 통해 부모 키워드 method에 접근 가능
this와 화살표 함수
- 컨텍스트 참조 가능한 키워드 (전역 context, 함수 context)
- 객체를 참조하는 역할, (호출 시점에 어떤 객체인지 동적으로 결정된다.)
- 함수 context
- 함수가 호출될 때 암묵적으로 this 가 전달된다.
- 함수 호출 방식에 따라 this에 바인딩 되는 객체가 상이
- ES6 화살표 함수 : this 바인딩 제공하지 않음 (apply, call, bind로 연결은 가능)
this 바인딩 - 함수 호출 방식
- 전역 객체에서 this 사용
- ServerSide : global
- BrowserSide : window
- 메서드의 내부 함수에서 this 사용은 전역객체를 참조하므로, 변수에 this를 미리 할당하거나, bind를 통해 필요한 객체에 바인딩하여 사용 가능하다.
- 메더스 내부에서의 this는
해당 메서드를 호출한 객체 바인딩
this 바인딩 - 생성자 함수 호출 방식
1
2
3
4
5
6
function Person (name) {
this.name = name;
}
const foo = new Person("kane")
foo.name // "kane"
- 생성자 함수 호출 시 동작
- 빈 객체 생성, this 바인딩
- this 는 빈 객체에 바인딩
- this로 속성 생성
- this를 사용하여 동적으로 속성과 메서드 생성
- 생성된 객체 반환
- 반환문이 없어도, 1번에서 생성되었던 객체가 반환됨
- 빈 객체 생성, this 바인딩
this 바인딩 - apply, call,bind
1
2
3
4
5
6
7
8
9
10
11
12
const foo = {
name : 'jay',
age : 30,
getName () {
function getAge() {
console.log(this.age) // 전역객체를 참조
}
getName.apply(foo)
getName.call(foo)
getName.bind(foo)()
}
}
- 함수명.apply(바인딩 객체, [함수 호출시 넘길 인자배열])
- 함수명.call(바인딩할 객체, 함수호출시 넘기는 인자1…)
- apply와 call은 사용즉시 함수가 호출 된다. (바인딩과 동시에)
- 함수명.bind(바인딩할 객체) ()
- bind는 바인딩할 객체에 연결된 새로운 함수를 값으로 반환
- 해당 함수를 따로 호출해주어야 한다.
this 바인딩 - 화살표 함수
- 화살표 함수에서는 this에 바인딩할 객체가 정적으로 결정된다.
- 항상, 상위 스코프 this를 가리킴 (Lexical this)
JS의 스코프
- 스코프 = 변수의 영역
- 변수가 유효성을 갖는 영역
Scope 규칙
- 변수 영역을 지정하는 규칙
- 정적영역 규칙 : Lexical Scoping Rule (JS가 따르는 룰)
- 소스코드를 구조를 기준으로
어디에 선언하였는지에 따라
스코프를 결정
- 소스코드를 구조를 기준으로
- 동적영역 규칙 : dynamic scoping rule
어디서 호출 하였는지에 따라 스코프 결정
- 런타임 때 결정됨
- 정적영역 규칙 : Lexical Scoping Rule (JS가 따르는 룰)
Scope의 종류
- 전역 스코프
- 소스코드상 모든 곳에서 사용할 수 있는 전역
- JS 는 window 객체
- 소스코드상 모든 곳에서 사용할 수 있는 전역
- file 스코프
- 해당 파일 전체에서 접근 가능, 다른파일에서는 접근 불가
- script type=”module” 로 조회되는 파일
- 모듈 스코프
- 모듈을 지원하는 프로그래밍 언어에서 모듈 단위 변수 선언가능
- 함수 레벨 스코프
- JS는 기본적으로 함수 레벨 스코프
- 지역변수 : 함수 내에서만 유효한 변수
- 함수 외부에서 유효하지 않음
- 블록 레벨 스코프
- 코드 블럭 내에서 유효한 변수 = 지역변수
- ES6 JS 부터 let, const 를 사용하여 블록 레벨 스코프 환경에서 개발이 가능해졌다.
실행 Context
- 코드가 실행 되는 범위에 대한 개념
- JS 엔진
- 코드 Read
- 코드평가 + (createoin Phase)
- 실행 컨텍스트
- 코드 실행 (Execution Phase)
- 동작
create Phase
- 코드 평가 단계 에서
Lexical Environment
생성 - 함수와 변수를 기록 : 선언,객체 정의 + this 바인딩,
- 외부 환경 참조 : 스코프 체인 형성
- 코드 평가 단계 에서
Execution Phase
- 코드 실행 단계 : 위→ 아래로 코드 실행
- 변수에 값 할당
- 함수 실행 코드가 있을 경우 함수 실행
실행 Context의 3가지 종류
global
컨텍스트 == 전역 컨텍스트- 함수 내의 코드가 아니라면 전역 컨텍스트에서 실행
functional
컨텍스트- 함수가 호출 될 때 마다, 함수에 대한 실행 컨텍스트 생성
- 각 함수들은 자신만의 컨텍스트 존재
- eval 컨텍스트
- eval 함수만의 실행 컨텍스트 존재
Call Stack
- stack 자료구조 (LIFO)
- 함수 호출시 만들어지는 실행 컨텍스트가 쌓임
- 한번에 하나의 일만 처리 가능
- JS엔진
- 코드 평가 → 실행 컨텍스트 생성 → 콜스택에 하나씩 적재 → 콜스택이 실행컨텍스트 실행 → stack에서 하나씩 제거
클로저
- 함수가 함수가 선언된 Lexical Environmert를 기억하여 내부 함수의 환경을 지속하는 상황
- 실행이 종료된 내부함수가, 내부함수가 선언되었던 Lexical 환경을 계속 참조하고 있는 경우
- 발생 조건
- 외부 함수 실행 컨텍스트 환경의
변수
를 참조하고 있는 내부 함수 실행 컨텍스트
- 외부 함수 실행 컨텍스트 환경의
1
2
3
4
5
6
7
8
const foo = '1';
function bar() {
const apple = 0;
return function () {
return apple;
}
}
- 함수가 종료되어도 스코프를 기억하는 것
- 특정 스코프에 접근할 수 있는 함수
- 상태유지
- 은닉화