JavaScript
자바스크립트는 인터프리터 언어입니다.
컴퓨터의 동장
사람이 이해할 수 있는 언어를 컴퓨터가 이해할 수 있는 기계어로 번역해야합니다.
-
컴파일러 언어
-코드작성 > Pre-processing > 기계어로 변환 > processing > 실행
-
인터프리터 언어
-코드작성 > Processing > 실행
-별도의 변환과정이 없습니다. 실행하는 과정에서 동시에 변환합니다.
Interpreter 언어 특징
- 컴파일 단계가 없음
- 컴파일러 언어에 비해 실행 속도가 느림
특징
- 변수의 타입
- 동적 타입 언어 : 변수에 들어가는 값에 따라서, 런타임에 타입이 추론됩니다.
- 타입을 지정하는 것이 아니라, 할당된 값에 따라서 타입이 변하는 것.
- 함수의 특징
- 함수는 일급객체의 특징을 가집니다.
- 함수는 개체와 동일하게 사용하게 사용할 수 있습니다.
- 함수는 값과 동일하게 취급합니다.
- 변수 할당문
- 객체 프로퍼티 값
- 배열의 요소
- 함수 호출의 인수
- 함수 반환문
-
상속의 형태
- 프로토타입 기반의 상속
- 언어가 갖고있는 프로토타입 체이닝 구조를 통하여 상속 가능.
클래스 기반이 아니라, 객체를 프로토타입화 하여 복제과정을통해 상속을 구현합니다.
-
패러다임 지원
- 명령형 프로그래밍 : 프로그램의 흐름을 단계별로 명시적으로 제어하는 방식.
- 함수형 프로그래밍 : 함수를 주요 구성 요소로 하는 프로그래밍.
- 객체지향 프로그래밍 : 객체 개념으로, 데이터와 행동을 캡슐화 하여 관리.
- 선언형 프로그래밍 : 무엇을 할지, 어떻게 할지는 시스템이 처리하고. 프로그래머는 결과를 정의.
- 그외 : 이벤트 기반 / 비동기 / 모듈화 프로그래밍 패러다임이 있습니다.
JavaScript 표준화
기술을 시간이 지남에 따라, 항상 더 나은 방향으로고도화 됩니다.
소프트웨어, 개발언어도 마찬가지로, 특정 시점을 기준으로 개선, 버전으로 관리됩니다.
JS 탄생
- Brendan Eich 라는 넷스케이프 개발자가 창시. (1995년)
- 초기 목적은 웹페이지의 보조적인 기능을 수행하기 위해 만들었습니다.
- 이름은 '모카' -> '라이브스크립트' -> '자바스크립트' 순서로 변하였습니다.
표준화의 필요성
각 회사는 자사 소프트웨어 사용의 점유율을 높이기 위해 브라우저마다 동작하는 기능을 경쟁적으로 추가하였습니다.
=> 같은 자바스크립트 파일인데, 브라우저 종류에 따라 동작이 달라지는 현상 발생 = 크로스 브라우징 이슈
모든 브라우저에서 자바스크립트는 동일하게 동작해야 한다 주장
- 1996년 표준화 개발 진행 (넷스케이프 -> ECMA 요청)
- 1997년 ECMA 총회때 채택
- ECMA-262에 표준화 목록에 추가되었으며, ECMA-262 기술 규격에 따라 정의하고있는 스크립트 언어를 'ECMA 스크립트 언어'라고 합니다.
버전마다 스펙이 상이하기 때문에 개발자는 버전을 고려하여 개발하여야합니다.
- 브라우저는 브라우저의 버전마다, 지원하는 자바스크립트 스펙이 상이. = ES의 기준을 따라가지 않음.
- 실제 표준화된 버전과 브라우저에서 지원하는 버전이 다를 수 있음
- 지원하는 기능들은 Caniuse 같은 사이트에서 확인이 가능 caniuse
ECMAScript 표기법
ECMAScript 버전 표기법
- ECMAScript 연도 - ECMAScript2015
- ES 연도 - ES2015
- ES 버전 - ES6
ECMAScript2015+
목적
- 대규모 어플리케이션
- 라이브러리 생성
- 다른 언어의 컴파일
을 대상으로 사용하는데 용이하도록 토대를 제공합니다.
개선사항
- 모듈, 클래스 선언, 블록레벨 스코프, inerator와 generator, 비동기 프로그래밍, promise, 구조분해 패턴 등의 개선
개발에 사용하고 싶지만, 브라우저 지원이 안될경우
polyfill과 babel을 사용
polyfill
- 지원하지 않는 브라우저에서 최신 기능을 제공하기 위해 필요한 코드
- polyfill은 브라우저가 다른방식으로 동일한 기능을 구현하는 문제를 해결하는데 사용
- 동일한 기능을 지원하는 스펙으로 다시 구현한 코드
babel
- 이전 버전의 브라우저에서 ES6 이전의 JavaScript로 변환하는데 사용되는 도구 (트랜스파일링)
- 문법을 번역 및 변환 polyfill 코드가 들어있는 서드파티를 활용하여 polyfill 기능도 사용가능
변수
데이터를 처리하는 과정에서 처리 흐름마다 값들을 기억해 둘 필요가 있습니다.
컴퓨터는 데이터를 기억하기 위해 메모리를 활용합니다. (기억장치)
메모리 : 메모리에 데이터를 담아 기억 / 각각의 위치 주소값이 존재 / 위치를 찾기 위해서는 메모리의 주소값 사용
변수
데이터를 담아둔 메모리의 주소를 쉽게 식별하기 위해 붙인 이름
메모리 주소값을 대신할 식별자를 지정하고, 식별자를 통해서 데이터에 접근합니다.
식별자 = 변수
변수 선언
- 키워드 var / let / const
- 변수명 (식별자 명)
- 할당 연산자
- 값
을 작성하여 사용합니다.
변수의 생성 단계
- 선언 단계 : 변수를 변수 객체에 등록 합니다.
- 초기화 단계 : 변수를 메모리에 할당하고, undefined(값이 없는 원시데이터)로 초기화 합니다.
- 할당 단계 : undefined로 초기화 된 변수에 실제로 값을 할당 합니다.
각 단계는 '코드 평가', '코드 실행'단계에서 이루어짐
변수의 키워드 ( var / let / const )
var
코드 평가단계 : 선언과 동시에 초기화 진행
코드 실행단계 : 값 할당 진행
초기화가 안된변수는 참조에러가 발생해야 하지만,
코드 평가단계에서 초기화가 되어있으므로, 변수의 할당문이 실행되기 전에도 참조가 가능합니다. (호이스팅)
var 키워드 특징/단점
- 키워드의 생략 가능 / 처음 값을 할당할 때와 재할당시의 모습이 동일하여 혼란
- 중복 선언 가능 / 초기 목적과 다르게 변수의 결과 예측에 어려울 수 있음
- 변수 호이스팅 / 실행 순서와 무관하게 변수참조가 가능 = 변수 결과 예측에 어려울 수 있음
- 전역 변수화 되어, 무분별한 변수 접근
- 위의 원인으로 의도치 않은 변수값 변경될 수 있음 = 코드 예측이 어려워짐
스코프
- 코드가 실행되는 과정에서, 변수와 같은 식별자를 찾아야하는 코드가 있을 때의 범위 규칙.
- JS에서의 스코프
- 전역 스코프 (global)
- 지역 스코프 (local)
호이스팅 : 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성 / 함수 호이스팅, 변수 호이스팅 등
ES6 (2015+) 부터 var 키워드의 단점을 해결하기위한 키워드가 let과 const 키워드
let / const
코드 평가단계 : 선언 진행
코드 실행단계 : 초기화, 값 할당 진행 // 실행이 될 때 변수를 정의한 코드를 만나기 전까지 변수를 참조할 수 없음 (ref err)
블록레벨스코프 : 코드 블록 내에서 접근 가능한 스코프
변수에 한정적으로 접근이 가능하므로, 예측 가능한 범위 내에세 변수 변경이 일어남
var v = 0;
function xyz() {
let a= 1;
while(a < 3) {
console.log(a);
a++
}
}
블록 = { }
let
const
- 재할당이 불가능, '상수 변수'를 선언할 때 사용 (수정불가)
- 무조건 값을 할당해야 합니다.
변수 네이밍 컨벤션
- Snake Case : 소문자와 '_'(언더바)를 사용합니다.
- Camel Case : 첫 단어는 소문자로 시작, 이후 부터 첫 글자를 대문자로 작성합니다. (기본적으로 자주사용함)
- Pascal Case : 각 단어 첫 글자를 대문자로 작성합니다.
- Constant Case : 전체글자를 대문자를 사용하고 '_'(언더바)를 사용(주로 상수변수에서 사용)
파일명의 경우 소문자와 -를 사용하는 kebab-case를 주로 사용합니다.
자료형
컴퓨터가 데이터 종류에 맞게 적합한 로직처리를 할 수 있게 데이터의 종류를 지정해주고, 알려주어야합니다.
데이터의 종류를 데이터 타입 = 자료형 이라고 합니다.
자바스크립트에서의 데이터 타입
원시 타입
- 값은 변경 불가능한 값입니다. (immutable value)
- 값으로써 전달됩니다. (참조 형태로 전달되는 것이 아님)
- 자바스크립트는 7가지의 원시 타입을 제공합니다.
String / Number / BigInt / Underfined / Null / Boolean / Symbol
원시 레퍼 객체
- 원시 데이터를 사용할 경우 해당 레퍼 객체들을 상속받아 사용할 수 있습니다. (원시 레퍼 객체 ≠ 원시 타입)
객체 타입
- 객체는 속성들을 변경할 수 있는 값입니다. (mutable value)
- 참조방식으로 전달됩니다. (Pass by reference) / 객체의 메모리 주소값이 전달
- 참조방식 과정중 데이터가 의도치 않게 변경될 수 있으므로 복사본을 전달해야합니다.
복사 방식에는 'deep copy', 'shallow copy' 이 있습니다.
원시타입
Number Type
- 숫자에는 정수, 실수가 존재. 다른 언어에서는 int, long, float, double 등의 형이 존재 합니다.
- 자바스크립트에서는 Number 하나의 숫자 타입만 존재 합니다.
- 자바스크립트는 모든 숫자를 실수로 처리 합니다. (= 정수타입 없음)
- 배정밀도 64비트 부동소수점 (IEEE 754 형식)
- 실수를 연산 할 때 근사값으로 처리합니다. ex) 0.1 + 0.2 가 0.3이 아닙니다.
- 숫자형에는 수 외에도, 무한대를 나타내는 Infinity와, Not a Number(수가 아님)인 NaN의 값도 존재합니다.
BigInt Type
- 임의 정밀도로 정수를 나타낼 수 있는 JavaScr4ipt 숫자 원시 값
- BigInt는 Number의 최대값을 넘는 정수도 안전하게 저장하고 연산할 수 있습니다.
- 다른 타입과 혼합하여 연산할 수 없습니다.
String Type
- 텍스트 데이터를 나타낼 때 사용합니다.
- UTF-16코드 단위의 시퀀스로 표현합니다. (UTF-16: 유니코드 문자 인코딩 방식 중 하나)
- 16bit 정수값의 요소로 구성된 집합
- 각 요소가 string 의 한 자리
- 0번째 index부터 시작
- 원시값은 불변합니다. = 문자값도 불변합니다. (각 요소는 변경 불가)
const a = 'apple'
a[0] = 'banana'
console.log(a)
=> apple
String Type 표기
- 따옴표나 쌍따옴표, 백틱(backtick)으로 감싸서 문자열임을 표현합니다.
- 템플릿 리터럴 표기법(` `)
- ES6 부터 사용가능합니다.
- 문자열 처리 기능을 제공 (줄바꿈 허용, 표현식 삽입 가능)
이러한 표현식 삽입을 String interpolation 보간(: 알려진 값에 알려지지 않은 값을 입력하는 과정) 라고 합니다.
console.log("My name is " + name + "I'm " + age)
console.log(`My name is ${name} I'm ${age}
Boolean Type
- 논리적 데이터 유형
- 참 or 거짓 값만 가질 수 있습니다.
ex) 상태값 checked 상태 / 특정 UI의 노출여부를 보여주는 변수의 상태 등
Undefined Type
- 변수를 선언한 후 값을 할당하지 않은 변수에 할당이 되는 값.
- 변수 초기화 단계에서의 Undefined는 개발자가 의도해서 넣은 값이 아닙니다.
- 의도적으로 넣을 수 도 있습니다.
let a
console.log(a)
=> undefined
Null Type
- 값이 없다는 것을 의도적으로 표현 할 때 사용합니다.
- 이전에 참조되었던 값을 의도적으로 더이상 참조하지 않겠다는 뜻으로도 사용합니다.
const a = 100
let z = a
console.log(z) ------ 100
z = null ------------ null
console.log(z) ------ null
- typeof null 은 'object'형으로 나오는데, 자바스크립트 typeof 연산자의 로직버그, 따라서 코드내에 명시적으로 null 타입을 확인 할 때는 typeof가 아닌 === (일치 연산자)를 사용하는 것을 권장합니다.
Symbol Type
- ES6에서 추가된 타입
- 중복되지 않는 유니크한 값 (객체의 Key 로 사용될 수 있습니다)
- 클래스나 객체형식의 내부에서만 접근할 수 있도록 전용 객체 속성의 키로 사용
- Symbol 함수를 호출하여 생성합니다.
const a = {
[Symbol.for('apple')] : 'fruit',
}
console.log(a[Symbol.for('apple')]) --- 'fruit'
=> fruit
Reference Type (객체타입)
- 객체타입, Object Type과 같은 말
- 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조 입니다.
- 객체 : 데이터(속성), 데이터에 관련한 동작을(Method)포함하는 개념적 존재.
- 원시 타입의 값을 제외한 자바스크립트에서의 모든 것은 객체 입니다.
- 객체타입은 변경 가능한 값(mutable) 입니다. // 객체의 속성을 변경, 추가, 삭제 가능
cf. 원시값 : 변경 불가능한 값 (immutable)
- 힙 메모리에 저장됩니다.
- 동적으로 변화 가능하므로, 메모리 공간 확보 및 저장이 가능
- Pass-by-reference : 참조 타입이므로, 참조값으로 처리됩니다.
- 여러 형태의 객체 타입
- 일반 객체와 함수
- 날짜
- 인덱스 컬렉션
- 키 컬렉션
등
동적 타입 언어
자바스크립트는 동적 타입 언어
의도적으로 타입을 변환할 수도 있지만, 의도와 상관없이 변경되기도 합니다.
- 명시적 타입 변환 (의도적)
- 암묵적 타입 변환 (의도적x)
명시적 타입 변환
자바스크립트 객체에는 객체별로 타입을 변환시키는 정적 메서드를 갖고 있습니다.
- 원시 레퍼 객체를 활용하여 개발자가 의도적으로 타입을 변경할 수 있습니다.
값.toString 문자열 타입으로 변환
Number(값) 숫자 타입으로 변환
Boolean(값) 불리언 타입으로 변환
암묵적 타입 변환
개발자가 의도하지 않았지만, 타입이 변환되는 경우.
값 + '' 문자열 타입으로 변환
값 * 1 숫자 타입으로 변환
!!값 불리언 타입으로 변환
- 값이 전달될 때, 참조되어 있는 변수 값 타입이 개발자의 의도와 다르게 암묵적 타입변환으로 변경될 가능성이 있습니다. = 타입 추론이 어려워져, 불필요하 디버깅 시간이 발생합니다.
|해결|
- 전달되는 시점마다 typeof나 일치 연산자를 사용하여 타입 guard구현
- 자바스크립트 superSet
타입스크립트 사용
함수
동일한 기능을 하는 코드의 중복을 줄이고 유지보수성을 높인, 특정 처리를 담당하는 처리기가 필요합니다.
함수 : 소프트웨어에서의 함수는 특정 동작을 수행하는 코드 일부분을 의미합니다.
- 외부 코드가 '호출'할 수 있는 하위 프로그램
함수의 형태
- input : 로직 처리를 위해 주입받는 데이터
- output : 로직 처리 후 반환되는 결과 데이터
- 본문 : 명령문의 시퀀스로 구성
함수의 구조
- 함수 이름 : 함수의 이름. (외부에서 호출시 이름이 사용됩니다.)
- 매개 변수 : 함수에 전달되는 인수. 유사배열 형태.
- 함수 몸체 : 명령 시퀀스들이 존재하는 블록
자바스크립트에서의 함수는 객체처럼 속성과 메서드를 가질 수 있습니다.
cf. 객체와의 차이 - 함수는 외부에서 호출이 가능합니다. / 객체는 외부에서 호출이 불가능합니다.
매개 변수 (parameter)
-
기본값 매개변수 (default function parameter)
- 매개변수 값이 없거나, undefined가 전달될 경우 대체되는 초기값
- 매개변수에 할당연산자와 함께 초기값을 할당
function a(arg = 1) {
return a
}
a()
=> 1
-
나머지 매개변수 (Rest parameter) (arg, ...rest)
- 가변항 함수 : 함수가 정하지 않은 매개변수를 배열로 받을 수 있는 함수. 정해지지 안흔 개수의 인자를 받을 수 있는 함수.
- spread 연산자 : 반복가능한 데이터를 열거할때 사용. 해당 연산자를 활용하면 매개변수를 배열 형태로 받을 수 있음.
function abc(arg, ...rest) {
console.log(rest) -------------------- [ 'b', 'c' ]
return arg
}
abc('a', 'b', 'c') ------------------- 'a'
-
arguments 객체
-
함수에 전달되는 인자들을 참조할 수 있는 객체
-
자바스크립트의 함수 : Function 객체 상속
-
Function 객체의 기본 속성 : arguments
-
형태 : 배열이 아니고 유사배열형태
- 배열 내장 method 사용 불가 (ex forEach 사용불가)
매개 변수(parameter)와 인자(argument)의 차이
매개 변수 : 함수를 정의할 때 상용되는 변수
인자 : 함수가 호출될 때 넘기는 값
function abc(p1, ...rest) {
console.log(rest)
return abc
}
abc() ------------------- undefined
abc(1) ------------------ 1
abc('a', 'b', 'c') ------ 'a'
일급객체
자바스크립트에서의 함수는 일급객체의 특징을 모두 갖고 있습니다.
아래 정의에 해당되면 일급객체 입니다.
- 일급객체는 함수의 실제 매개변수가 될 수 있다.
- 일급객체는 함수의 반환값이 될 수 있다.
- 일급객체는 할당명령문의 대상이 될 수 있다. (변수 등에 할당 가능)
- 일급객체는 동일비교의 대상이 될 수 있다. (값으로 표현 가능)
함수의 생성과 사용패턴
함수 생성
-
함수 선언문 : 기본적인 함수구조로 함수를 생성
-
함수 표현식
- 함수를 변수에 할당하는 방식.
- 익명 함수(anonymous function) : 함수명을 생략하고 변수명을 함수처럼 사용합니다.
- 기명 함수(named function) : 함수명을 생략하지 않음. 외부에서 기명함수를 호출하게 되면 함수가 할당된 변수명을 참조해서 호출되기 때문에 외부에서 기명함수의 함수명으로는 호출할 수 없습니다.
const a = function b() {~~~} 함수를 console.log(b())처럼 사용하면 referenced Error 된다는 말
-
Function 생성자 함수 (일반적으로 사용되지 않는 방법)
- 자바스크립트 내장 객체(빌트인 객체) 중 하나
- 함수 표현식, 함수 선언문 은 Function객체를 통해서 함수를 생성하는 방법을 단순화한 축약법
const a = new Function(arg1, arg2, ..., 'return 1')
a(1)
=> 1
-
화살표 함수 표현식 (익명함수)
- ES6 이후부터 사용 가능
- function 키워드를 사용하지 않고, 화살표(
=>)를 사용.'
- 일반적인 함수와 동작로직에 차이가 있음.
const a = (arg) => {
return arg()
}
함수 사용 패턴
-
IIFE (즉시 실행 함수)
- 함수 정의 동시에 실행
- 코드평가 -> 코드실행 -> 최초 1회 실행
- 작성 방법
- 즉시 실행할 함수 괄호로 감싸기
- 괄호로 감싸진 함수를 실행
- 재귀함수 (Recursive function)
- 자기 자신을 호출하는 함수
- 계속 자신을 참조하여 호출하므로 = 모한히 호출 될수 있음
- 직관성이 떨어질 수 있어, 한정적 사용 권장
- 중첩함수 (inner function)
- 함수내에 정의된 함수 = 내부함수
- 내부함수 내의 변수 참조 -> 내부함수는 부모를 포함한 변수부터 부모 외부 범위 참조(접근) 가능
- 부모함수 내의 변수 참조 -> 부모함수는 자식 범위 참조 불가능(자식 함수의 변수들에 접근 불가능)
- 스코프 체인
- 콜백함수 (Callback function)
- 함수의 매개변수로 사용 / 인자로 전달받은 함수를 의미
- 함수 A가 인자로 B함수를 받음
- A함수가 호출되는 시점에 B함수도 호출
- 특정 이벤트가 발생했을 때 호출