[FrontEnd] ECMAScript (일주일동안 언어 자체에 대한 세부적인 내용) → React
[BackEnd] Java (언어 자체에 대한 자세한 내용, 객체 지향)
[DataBase] servlet
[Framework] Spring
순서로 진행됩니다 !!
1995년 Netscape 사의 “브랜든 아이크”
Prototype기반의 함수형 언어로 Web에서 사용가능한 언어 → Macha → LiveScript → (마케팅의 이유로)JavaScript
이렇게 JavaScript가 탄생되고,, 언어에 대한 표준화가 진행된다.
[표준화 진행] ECMA(비영리 표준기구)에서 ECMAScript(우리가 알고 있는 JavaScript)라는 이름으로 표준화된다.
💡 ECMAScript와 JavaScript는 같은 것일까?
→ 아니, 실제로는 다르다!
우리가 흔히 말하는 JavaScript는 이렇게 구성된다.
JavaScript = ECMAScript + [client side web API(BOM, DOM, …) or Host API]
ECMAScript 2015를 ES6라고 한다.
ECMAScript 2016를 ES7 … ECMAScript 2021 ES12가 가장 최신버전.
💡 왜 모든 책마다 ES6를 다룰까?
1. ES5에서 ES6로 넘어갈 때 새로운 개념이 많이 심어지고 언어 자체에 대격변이 일어났다.
2. 모든 브라우저에서 원활하게 돌아가는 버전이 ES6이다. (브라우저마다 돌아가는 방식이 다르다. → 실제로 동작하는 자바스크립트 엔진은 벤더들이 만들기 때문에!)
MS에서 표준 아닌 표준처럼(비표준) JScript를 만들고 fragmentation(파편화) 현상이 일어났다.
→ 해결해준 것이 jQuery(라이브러리)
jQuery는 프레임워크가 아닌 라이브러리이다. (좋지만 단점도 있다 !)
ECMAScript(JavaScript)가 사람들에게 점점 잊혀지게 되고..
다시 사람들에게 주목받게 된 계기가 있는데 HTML, CSS의 탄생 !
HTML, CSS → W3C가 표준을 관장
1999년 12월 HTML4.01 버전을 마지막으로 더이상 업데이트는 없다고 발표
📌 WHY??? HTML의 문제점
1. HTML은 정형성이 없다. (코드의 문법적인 내용이 조금 틀려도 브라우저에 잘 렌더링됨) → 유지보수에 문제가 생김
2. 확장성이 없음(유저가 태그를 만들어서 사용할 수 없음. 새로운 것을 만들 수 없음.)
→ HTML에 XML을 넣어서 해결함. (XML은 정형성이 있다.)
HTML + XLM ⇒ XTHML 1.0
(2000년 1월)
그러나 XTML을 외면하는 기업들이 생기고..
→ WHATWG에서 HTML을 독자적으로 발전시킬 연구를 하게되고 HTML5
가 탄생한다.
그 결과 현재 웹의 표준은 HTML5
가 되었다!!
HTML5 = HTML(25%) + CSS3(5%)+ JavaScript web API (70%)
그렇게 JavaScript의 위상이 올라간다.. !
2009 → ES5 나오고 다시 열심히 표준화가 진행되기 시작함.
TypeScript
는 MS에서 2012년에 만들었다.
TypeScript라는 하나의 프로그래밍 언어로 열심히 코드를 작성하고 transpile(compile(x))을 하면 결과가 머신코드가 아닌 JavaScript가 나온다!
→ 이런 프로그래밍을 Meta Programming
이라고 한다.
💡 Meta Programming을 하는 이유는 JavaScript에 없는 기능을 TypeScript를 통해 기능을 추가할 수 있기 때문이다. TypeScript를 통해 클래스 기반의 객체지향프로그래밍이 가능하다.
TypeScript는 그냥 한번 만들어 본 언어가 아닌 상당히 영향력 있는 언어라는 것을 알아두자.
ES6 ⊂ ES7 ⊂ TypeScript
TypeScript는 ECMAScript의 SuperSet‼️ (TypeScript는 ECMA의 문법을 모두 포함하고 있다.)
브라우저 안에 갇혀있었던 JavaScript가 Node.js
의 탄생으로 격상하게 되었다 !!
→ JavaScript로 일반적인 어플리케이션을 만들 수 있게 됨.
Node.js의 탄생으로 ECMA가 발전하면서 💥ES6(ECMA 2015)💥가 나오게 된다. (ES5와 ES6 사이의 변화가 굉장히 크다.)
Package Manager
: 어플리케이션을 사용할 때 필요한 라이브러리를 설치, 유지, 관리하게 해줌. 모듈간의 dependency 즉 version을 맞춰준다!Transpiler
자동화 도구
: build, test, deploy를 자동화시켜줌.모듈화
: 하나의 파일로 싹 모아줌Framework
JavaScript를 실행하려면 JavaScript Engine이 필요하다.
JavaScript Engine은 browser 안에 내장되어 있다.
가장 많이 사용하는 브라우저는 구글의 Chrome
Node.js는 V8 engine 사용
Browser | JS Engine |
---|---|
Chrome | V8 |
Edge | Chakra |
Safari | Webkit |
Firefox | SpiderMonkey |
단축키
extension 설치
ctr + opt + n
vscode 설정
CPU → 연산
데이터 → memory
memory cell을 사용하기 위해서는 memory 주소를 알아야 한다!
→ momory주소를 알아내기 위한 매커니즘은 바로 Variable(변수)
이다. 왜냐하면 memory 주소에 대한 직접적인 access가 불가능하기 때문이다.
대부분의 프로그래밍 언어는 오류 발생의 위험성을 줄이기위해 메모리 주소의 직접적인 접근을 금지한다. (예외적으로 C언어는 직접적인 메모리 주소를 사용할 수 있다.)
변수 → 식별자(identifier): 다른 것과 구별하기 위한 이름(함수 이름도 식별자임
식별자의 Naming Rule
JavaScript 변수 생성 방법
var
→ function-level scopelet
→ block-level scopeconst
→ block-level scope(let
과 const
는 ES6로 인해 생김.)
var score;
메모리 구조(memory cell)표현 예시
0x … | … | |
---|---|---|
score → | 0x2763 | undefined |
0x32F7 | ||
… | … | |
.. | .. | |
.. | .. |
변수 score가 0x2763 이라는 memory cell을 가리키고 그곳에는 undefined가 저장된다.
undefined
💡 그렇다면 어딘가에는 score라는 변수가 저장되어 관리되어야 한다.
→ 식별자들은execution context
에 key/value 형태로 저장된다.
console.log(score); // 변수를 먼저 콘솔에 찍고
var score; // 나중에 변수를 선언
→ reference error(참조 에러)가 나야 정상인데 실행 결과는 error가 아닌 undefined라는 원시값이 나온다.
자바스크립트는 모든 식별자를 먼저 검사하고 판단 후에 코드를 실행(런타임)한다.
(var score;를 만났을 때 score에 undefined를 넣고 난 후에 console.log를 실행하게 됨.)
아래에 있는 코드가 위로 올라가는 현상이 발생한다! → 이것이 바로 호이스팅
호이스팅
💡 자바스크립트의 모든 식별자는 호이스팅 처리가 된다.
var 키워드로 변수 선언 시 주의점
var x = 1;
var y = 2;
// 자바스크립트에서 var 키워드로 변수의 중복선언이 가능하다.
var x = 100; // 가능. 사실은 중복선언이 아니라 위에 중복된 변수가 있다면 무시하고 var 키워드가 없는 것처럼 동작함.
var y; // 가능. 초기화 구문이 없으면 코드 자체를 무시.
console.log(x);
console.log(y);
var x = 1; // 전역변수
if(true){
var x = 100; // var로 선언된 이 x는 지역변수가 아니다!!
// var 키워드는 if문의 scope를 scope로 인정하지 않는다. (var은 함수 레벨의 scope를 생성한다.)
// 따라서 위의 var x = 1에서 선언한 x가 중복 선언된 것이라고 보면 된다.
}
console.log(x); //100
for(var i=0; i<5; i++){
console.log(i);
}
console.log(i); // for문 내에서 선언한 i가 5가 되어 그대로 출력
var x = 1; // 전역변수
function myFunc(){
var x = 100; // function-level scope
console.log(x); //100
}
myFunc(); //100
console.log(x); //1
호이스팅이 영역별로 일어난다. (함수 레벨에서 호이스팅이 별도로 일어난다.)var x = 1; // 전역변수
function myFunc(){
console.log(x); //undefined
var x = 100; // function-level scope
}
console.log(x); //1
myFunc(); //undefined
“ES6” → let
, const
let 키워드의 특징(var 키워드와의 차이점을 잘 알아두자)
let x = 100;
let x = 1; // SyntaxError: Identifier 'x' has already been declared
let score = 100;
{ // block-level scope
let score = 10;
let myVar = 1;
}
console.log(myVar); // ReferenceError: myVar is not defined
console.log(myVar);
let myVar = 100; // ReferenceError: myVar is not defined
let은 선언과 동시에 초기화가 되지않는다. let을 사용하면 해당 변수를 메모리에 올리지만 undefined를 주지 않아(초기화가 되지않는 상태) 변수를 사용할 수 없는 상태가 되기 때문이다.let myVar = 1; // global variable
{
console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
let myVar = 100;
}
코드 블록 내의 myVar은 현재 사용할 수 없는 상태이기 때문에 console.log(myVar)에서 ReferenceError가 발생한다.Temporal Dead Zone(일시적인 데드존)
const
: 상수를 선언할 때 사용(변수에 대한 재할당 금지)메모리 구조(memory cell)표현 예시
var score;
0x … | … | |
---|---|---|
score → | 0x33 | undefined |
0x67 | ||
… | … | |
.. | .. | |
.. | .. |
score = 80;
0x … | … | |
---|---|---|
0x33 | undefined | |
0x67 | ||
… | … | |
score → | .. | 80 |
.. | .. |
primitive value(원시값)은 변할 수 없다.(immutable(불변)의 특징을 갖는다.) 즉 primitive value(원시값)인 undefined는 바뀌지 않고 변수 score가 가리키는 참조가 바뀐다. 사용되지 않는 공간인 undefined가 있는 공간은 언젠가(언제가 될지는 모른다.) garbage collector(청소기)에 의해서 garbage collection(청소)이 발생한다.
_
, $
제외)💡 자바스크립트는 camelCase와 PascalCase 사용
literal
: 특정 값을 표현하기 위해 사람이 이해할 수 있는 문자나 약속된 기호를 이용하는 notationHello
statement(문)
: 프로그램의 최소 실행 단위, 프로그램은 statement의 집합이다.생략하면 ASI(Automatic Semicolon Insertion(자동 세미콜론 삽입))가 동작한다.
but, 명확한 code를 위해서 세미콜론을 생략하지 말고 붙여주자.
{ } 와 같은 코드 블럭을 나타내는 기호 뒤에는 ; 세미콜론을 붙이지 않는다. 자체적인 종결 기능을 가지고 있기 때문이다.
let myVar = 1 // 세미콜론을 찍지 않아도 error가 발생하지 않는다. -> ASI
{
console.log(myVar)
} // 세미콜론 찍지 않음.
expression(식)
: 평가 과정을 통해 값으로 인식되는 구문총 7개의 data type
let myVar = 1.0;
console.log(myVar === 1); //true
// 모든 변수는 64bit 실수로 처리함.
console.log(3/2); //1.5
// (cf) Java에서는 정수 나누기 정수는 정수이므로 1이 출력된다.
let str = '이것은 \n소리없는 \n아우성';
console.log(str);
let str1 = `이것은
소리없는
아우성`;
console.log(str1);
// 출력은 아래와 같다.
/*
이것은
소리없는
아우성
*/
let name1 = '홍길동';
console.log('내 이름은 ' + name1 + '입니다.');
console.log(`내 이름은 ${name1}입니다.`)
// 출력은 아래와 같다.
// 내 이름은 홍길동입니다.
인자를 사용할 수 있지만 실제 symbol값에 영향을 주지는 않는다. Symbol()의 인자는 description(꼬리표)같은 기능이다.
const mySymbol = Symbol(); // Symbol 함수 호출
console.log(typeof mySymbol); //symbol
console.log(mySymbol); //Symbol(), 값이 노출되지 않는다.
const mySymbol1 = Symbol();
const mySymbol2 = Symbol();
console.log(mySymbol1 === mySymbol2); //false
// Symbol()의 인자는 description(꼬리표)같은 기능임. 심볼값과는 아무 관련이 없다.
const mySymbol3 = Symbol('소리없는 아우성');
const mySymbol4 = Symbol('소리없는 아우성');
console.log(mySymbol3 === mySymbol4); //false
console.log(mySymbol3.description); //소리없는 아우성
if(mySymbol1){ // symbol값을 논리값으로 사용할 수 있음.
console.log("있어요!");
}
const s1 = Symbol.for('mySymbol');
// global symbol registry(전역 심볼 저장소)라는 곳이 있다.
// 여기에서 해당 인자를 key로 가지고 있는 symbol을 찾는다.
// 만약 해당 symbol이 존재하지 않는다면 symbol을 만들고
// global symbol registry에 등록하고 symbol을 리턴한다.
const s2 = Symbol.for('mySymbol');
console.log(s1 === s2); //true
console.log(Symbol.keyFor(s2)); //mySymbol
const Direction= {
// 방향을 나타내는 4가지 property
/*
'UP': 1,
'DOWN': 2,
'LEFT': 3,
'RIGHT': 4
*/
// 뒤의 value값이 바뀌는 경우 error가 일어날 확률이 크므로 값을 Symbol처리한다.
'UP': Symbol(),
'DOWN': Symbol(),
'LEFT': Symbol(),
'RIGHT': Symbol()
}
let myDirection = Direction.UP;
if(myDirection == Direction.DOWN){
// 내 방향이 DOWN일 때 실행할 코드
}
→ 1 ~ 6은 Primitive type(원시 타입, 불변함), 7은 Reference type(가변함)
💡 지금까지는 데이터 값에 대한 Data type을 알아보았다.
그렇다면 변수에도 Data type이 있나요??
JavaScript 변수에 값이 할당되는 시점에 Type이 결정된다.
→ Type inference(타입추론)에 의해서 dynamic typing(동적타이핑)이 결정된다.
동적타이핑이 일어나는 프로그래밍 언어(JavaScript)를 dynamic type language(동적 타입 언어) 또는 weak type language라고 부른다.
- 묵시적 타입 변환이 많이 일어난다.
- 엄격하지 않기 때문에 자율성이 많이 부여된다.
- 유연하고 효율적인 프로그래밍이 가능하다.
- 신뢰도가 떨어진다.
- 많이 한 사람이 잘합니다. >> 자바스크립트를 잘하는 사람이 별로 없다!(인력이 귀하다.)
(cf) Java같은 경우에는 변수에 type을 명시한다.
이러한 언어를 static type language(명시적 타입 언어) 또는 strong type language라고 부른다.- 명확하기 때문에 type error가 발생할 확률이 적다.
- 효율적이지 않지만 신뢰도가 높다.
- 공부하기 편하다.
- 유연하지 않고 정해져있기 때문에 5년하든 10년하든 비슷하다.
연산자 오버로딩과 묵시적 형변환
/* 묵시적 형변환 */
// 숫자를 문자열로 바꿔서 연산함
console.log(1 + '2'); //12
// true를 1로 변환
console.log(1 + true); //2
// null을 0으로 변환
console.log(1 + null); //1
console.log(1 + undefined); //NaN
형 변환(String)
+
연산자를 이용console.log(typeof String(1)); //string
console.log(typeof String(NaN)); //string
console.log(typeof (1).toString()); //string
==
===
typeof
👍🏻❤️