JavaScript
20210208_JavaScript01 JS의 역사와 미래, ES이해, JS문법, 자료구조
JavaScript01
- JavaScript에 대해 공부하기 위해서 유튜브 '드림코딩by엘리' JavaScript 강의를 들었다.(강의를 꼭보길 바란다 너무 잘되어 있다.)
- 물론, documents 를 보는 것도 좋지만 먼저 강의를 보고 documents를 보려고 한다.
- 정말 강의를 풀어내는 방식이 깔끔하고 의문점 갖게 해주고 잘 설명해 주신다~ 생활코딩님 처럼 너무 잘하신다~
JavaScript의 역사와 미래
- Netscapte 회사
- Mosaic web Browser(Marc Andreessen) -> Netscape사의 Netscape Navigator 브라우저(1994) "정적인 웹사이트" -> "동적인 웹사이트"에 대한 갈망
- Script 언어 추가 (Brendan Eich의 Scheme언어 변형-> Mocha언어 -> LiveScript언어(interpreter 포함한 브라우저))
- JavaScript로 이름 변경 - JavaScript와 JavaScript interpreter 출시(1995)
- Macrosoft 회사
- Netscape 사의 JavaScript를 Reverse engineering 해서 JScript로 내놓음
- 이를 가지고 Internet Explorer 브라우저를 내놓았음
- 개발자의 고충01
- 두 웹사이트에서 동시에 동작하게끔 해야 했음 -> 두 양대산맥 때문에 너무 힘듦
- ECMAScript1의 탄생
- Netscape 에서 ECMA International 단체에 JavaScript 표준화 시도 -> browser 동작언어 규칙 표준화 -> ECMAScript1(1997)
- ECMAScript1~ECMAScript4 (더 많은 기능과 효율화에 대한 논의와 표준화)
- Internet Explorer의 독재
- 95% 사용자를 가진 IE가 더이상 ECMAScript에 대해서 따르지 않겠다고 함(2000)
- Firefox의 출연
- Mozilla 회사의 Firefox 브라우저 탄생(2004)
- ActionScript3와 Tamarin엔진을 권유하며 ES4에 대한 재검토 제안(기존과 너무 달라서 힘듦)
- 개발자의 고충02
- 브라우저 시장의 삼파전 양상을 가짐(표준안이 어렵고-> 다 따로따로 힘들었음)
- AJAX의 탄생
- AJAX (Asynchronous JavaScript and XML) - Jesse James Garrett
- 비동기적으로 서버에서 받아오고 처리가능하게 해줌
- 개발자의 고충03
- 너도 나도 새로운 브라우저가 양산되기 시작함 (너무 힘들다)
- 개발자 커뮤니티 활성화
- JQuery, Dojo, Mootools 탄생"
- 다른 브라우저를 신경쓰지 않아도 되게 만드는 것
- 해당 기술의 API만 쓰면 해당 기술이 알아서 다른 브라우저에서 동작하게 변환해 주겠다.
- Jquery의 보편화
- Chrome브라우저 탄생
- Google회사의 Chrome 브라우저를 시장에 출시함(2008)
- Chorme은 interpreter로 JavaScript 실행에 엄청 강력한 엔진인 JIT(just-in-time compilation)을 가지고 있었음
- ES4의 탄생
- Chrome, Firefox, IE, Netscape 가 표준화에 대해 서로 논의하여 ES4를 만듦
- ES6(2015)
- default parameter, class, arrow function, conset, let 등을 정의해 놓음
- 커다란 변화는 ES5, ES6에 있음
- JavaScirpt의 정착
- 성숙되고 잘 정착됨
- 더이상 Jquery, dojo, mootools 등의 라이브러리 도움이 필요 없어짐
- 브라우저에 따른 ES를 위한 엔진
- Chrome : V8
- Firefox : Spider Monkey
- Safari : JScore
- MS Edge : Chakra
- Opera : Carakan
- Adobe Flash : Tamarin
- TypeScript, BABEL
- 최신 버전의 ES를 쓰고 싶은 개발자는 TS(TypeScript)를 사용
- 개발시에는 TS 쓰고 사용자에게 올라갈때(배포)시에는 ES5, 6로 하기 위해 BABEL이라는 엔진이 JavaScript를 번역하여 컴파일 해줌
- SPA(Single Page Application)
- 현재 한 페이지에서 부분적으로 데이터를 받아와 업데이트하는 것(SPA)이 유행하고 있음
- 이를 쉽게 만들기 위해서 React, Angular, Vue, Backbone 등의 라이브러리, 프레임 워크등이 생겨남
- Javascript 활용
- node.js : V8 엔진을 기반으로 한 backend에서 구현가능하게 함
- React Native , Apache Cordova : mobile 어플리케이션이 구현이 가능함
- Electron : desktop 어플리케이션도 가능함
- Web Assembly
- 원래 유일하게 브라우저에서 동작하는 언어는 JS였지만 Web Assembly를 통해서 원래 프로그램 언어인 python, java, c#, c++, go 등의 언어로 웹 어플리케이션을 만들수 있게 됨
javaScript02
JavaScript - Hello, World 출력하기
- VScode에서 main.js 파일 만들기
console.log('Hello World!');
- index.html 파일 만들어서 js 연결하기
! + tab
: html 구조 만들기<script src="main.js"></script>
추가해서 연결
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="main.js"></script>
</head>
<body>
</body>
</html>
- CLI의 node.js를 통해서 확인
- node.js 설치
node main.js
-> Hello World! 출력 확인
- 브라우저에서 확인하기
- VScode 에디터에서
ctrl + shift + p
에서live server : open with live server
실행 - 브라우저에서
ctrl + shift + i
로 개발자 툴 켜기 - console 탭에서 Hello World! 출력 확인 (
console.log()
)
- VScode 에디터에서
- 둘다 확인이 가능한 이유 : node.js , Web APIs 모두 console 관련 API가 있고 Interface가 둘다 동일
- Node.js console-docs vs Mozilla console-docs
- API(Appication Programming Interface)로 Web APIs는 JS가 아닌 브라우저가 제공하고 이해할수 있는 함수임
- 브라우저에서 제공하는
Dev Tools
잘 활용하기 (ctrl + shift + i
) - 공부시 MDN 공식 사이트에서 예제를 통해서 공부하기
JavaScript - async vs defer
- Script를 HTML Head에 포함하는 경우
- 브라우저는 1줄 씩 분석하여(parsing HTML) CSS와 병합해서 DOM 요소로 변환함
- 브라우저가 1줄 씩 분석하다가 Script를 만나면 분석을 중지하고 script를 다운 받아서 실행하고 다시 분석함
- parsing HTML -> fetching js -> excuting js -> parsing HTML
- 단점 : 중간에 다운 받는 Script가 크면 페이지 출력시 너무 오래 걸림
- Script를 HTML Body 끝에 포함하는 경우
- HTML을 모두 분석하고 준비된 상태에서 js를 다운 받기에 사용자가 js를 다운 받기전에도 볼 수 있음
- parsing HTML -(pags is ready)-> fetching js -> excuting js
- page를 구성하는 요소가 js가 중요하게 작용하는 경우 페이지를 온전히 보기힘들고 마지막 까지 기다려야함
- Head에 async를 사용하여 Script를 넣는 경우
- script 속성값으로 async 사용시 병렬로 js를 다운 받고 실행함(async boolean 타입의 자료임)
- parsing HTML + fetchin JS -> executing js -> parsing HTML
- 병렬로 다운 다운로드 시간 절약가능
- 단점 : 먼저 JS가 실행되기 때문에 정의 되어있지 않은 요소가 있는 경우에 문제가 발생함
- 또한, 다운 받고 실행 순서가 요구 되어지는 경우, 다운 용량에 따라서 순서가 바뀌기 때문에 문제가 발생함
- Head에 defer를 사용하여 Script를 넣는 경우
- defer속성 사용시 병렬로 js 다운만 받고 HTML 분석 끝나고 js를 실행
- 다운 받았을 때도 나중에 js를 실행하기 때문에 순서대로 실행을 시킬 수 있음
- 제일 효율적이고 안전함
JavaScript - 'use strict'
'use strict';
를 제일 상단에 사용하는 경우 선언 되지 않은 변수의 활용 등의 문제를 줄일 수 있음. 자율도가 높은 만큼 오류가 많아 질수 있으므로 이러한 문법들을 조금더 제한하여 사용하게 할 수 있고, JS 엔진이 더 효율적으로 인식가능하여 성능 개선도 됨(TS에서는 안해도 되지만 바닐라 JS의 경우엔 무조건 사용하는 편이 좋다.)
javaScript03 문법
- 프로그래밍 중요 요소
- 프로그래밍 언어 3요소 : 입력, 연산, 출력, (전송)
- CPU에 최적화된 연산
- 메모리의 사용을 최소화
JavaScript - variable(let)
let
(함수는 ES6에서 등장함)- 어플리케이션 마다 제한적으로 메모리가 할당되고 값은 메모리에 할당됨
let
을 통해서 메모리를 가리킬 수 있음 (point)
let name = 'raccoon';
console.log(name);
name = 'hello';
console.log(name);
JavaScript - Block scope vs Global scope
{}
(Block scope)- 블록의 경우 코드 접근을 제한 할수 있음
- 블록 안에서 변수는 블록 안에서만 가능하고 밖에서 접근 못함
{}의 외부
(Global scope)- 블록내부의 코드 및 외부 변수 모두 접근 가능
let globalName = 'globalName';
{
let name = 'raccoon';
console.log(name);
console.log(globalName); // 출력!
}
console.log(name) // error
console.log(globalName); // 출력!
JavaScript - variable(var)
var
(옛날 부터 쓰던 변수 선언 함수)- 절대로 쓰지 말것!!!!!
block scope
도 무시하고var hoisting
이 일어남- 값이 먼저 할당 되어도 어디서든지 선언이 되면 어디서든지 호출이 됨
var hoisting
: 선언이 제일 위로 올라가서 어디에서든지 변수에 접근해도 접근 가능함
정리하자면,
var
,let
둘다 선언 자체는 존재 해야함그런데
let
의 경우에는 순서가 존재하여 먼저 선언이 되어야 변수에 접근 가능(지우던, 바꾸던, 호출하던)var
의 경우에는 변수 선언이 어느 위치에 있떤 일단 존재하면 가장 위에서let
이 선언 된것과 마찬가지이므로 호출, 바꾸기 위치가 중요하지 않다.
// console.log(globalName); // error
// globalName = 3 // error
// console.log(globalName); // error
{
let name = 'raccoon';
console.log(name);
console.log(globalName);
console.log(age); // undifined 출력
}
console.log(name)
console.log(globalName);
console.log(age); // undifined 로 결과 출력
age = 4 // 변수에 값 할당 먼저 함
console.log(age); // 4 출력
var age; // var만 있으면 무조건 접근 가능해짐 순서 상관 없이(가장 위로 가서 선언 되니까)
JavaScript - Constants
const
- 한번 변수 할당이 되면 절대로 값 변경 불가함(즉, 접근 불가)
- 보안, 스레드 안전성, 코딩실수 줄이기 등의 이유로 사용
- Mutable(
let
) vs immutable(const
)
const k = 7;
console.log(k);
k = 8; // type error
console.log(k); // 앞에서 이미 error, 여기서도 error겠지만
JavaScript - Variable types
- Primitive Variable(원래, 원시 변수 - single item을 더이상 나누어 질수 X) : number, string, boolean, null, undefined, symbol
- Object (box container - single item들을 여러개 묶어서 한단위로 관리)
- Function (first-class funciton : 함수도 다른 데이터 타입 처럼 변수에 할당이 가능하고 parameter(인자)로 전달도 되고 return타입으로 불러올수도 있음)
- java, c 언어의 경우 메모리 크기에 따라서 세부적으로 type이 나뉨 그런데 JS에서는 메모리크기 상관 없이 특성에 따라 통일 되어 있음
Number
- 정수(integer), 소수(decimal number) -> type은 Number임
- 양의 무한(infinity), 음의 무한(-infinity), 숫자가 아님(NaN) -> type은 Number임
const count = 17; // integer
const size = 17.113; // decimal number
console.log(`value: ${count}, type: ${typeof count}`);
console.log(`value: ${count}, type: ${typeof count}`); // 모두 number type으로 들어감
const infinity = 1 / 0;
const negativeInfinity = -1 / 0;
const nAn = 'not a number' / 2;
console.log(`value: ${infinity}, type: ${typeof infinity}`); // 양의 무한
console.log(`value: ${negativeInfinity}, type: ${typeof negativeInfinity}`); // 음의 무한
console.log(`value: ${nAn}, type: ${typeof nAn}`); // 숫자가 아님
// 값은 위처럼 뜨지만 , type는 모두 number임 , 그리고 error를 내지 않음
BigInt
- JS에서 숫자는
-2**53 ~ 2**53
까지가 연산시 안전한 값이라고 한다..(대략 연산으로 출력하는 자리값은 대충 22 자리까지 가능한 것 같다.) - 넘어버리면, e를 가지는 숫자로 표현됨
- 그런데 23자리 이상 숫자에 끝에
n
을 붙이면 모두 표현되고 type은bigint
로 표현됨
const notbigInt = 1234567890123456789012345678901234567890;
console.log(`value: ${notbigInt}, type: ${typeof notbigInt}`);
const bigInt = 1234567890123456789012345678901234567890n;
console.log(`value: ${bigInt}, type: ${typeof bigInt}`);
String
- 변수에 할당 할 수있고,
str + str
가능하다. - 특이점은
숫자
와 덧셈시 숫자를 문자로 인식하여 출력한다. - 그리고 python의
문자 * 숫자
경우에 반복 문자사용은 js에서 하지 않는다. - type는 string으로 출력
- template literals(string) 기능 (즉 python에서의 문자 포매팅 기능) 은
`글자${변수}글자`
를 통해서 포매팅이 가능하다.
const k = 'str'
console.log(k + 'string'); // strstring
console.log(k + 3); // str3
console.log(k * 3); // NaN
console.log(k / 3); // NaN
console.log(k - 3); // NaN
console.log(`value: ${k}, type: ${typeof k}`);
// value: str, type: string
Boolean
- false : 0 , null, undefined, NaN '' (반면에 python에서는 undefined, NaN 등은 error처리함)
- true : 이외의 값들
- null , undefined, NaN의 경우 값은 모두 각 이름을 출력하고 type은 모두 다르다. (null : object, undefined : undefined, NaN : number)
const canRead = true;
const test = 3 < 1; // false
const k = NaN
console.log(`value: ${canRead}, type: ${typeof canRead}`);
console.log(`value: ${test}, type: ${typeof test}`);
console.log(`value: ${k}, type: ${typeof k}`); // NaN , number
let nothing = null;
console.log(`value: ${nothing}, type: ${typeof nothing}`); //null, object
let x;
let y = undefined;
console.log(`value: ${x}, type: ${typeof x}`); // undefined : undefined
console.log(`value: ${y}, type: ${typeof y}`);
Symbol
- 고유한 식별자가 필요한 경우
- string을 식별자로 쓰는 경우 다른 파일이나, 모듈에서 동일한 string을 사용할때 같은 식별자로 간주하기 때문에 문제가 됨
- 동일한 식별자로 쓰고 싶다면
Symbol.for
사용 하여 할당 - symbol출력시 항상
Symbol객체명.description
으로 변환해서 출력해야함
const symbol1 = Symbol('id');
const symbol2 = Symbol('id');
console.log(symbol1 == symbol2); // false
// 동일한 식별자로 쓰고 싶다면 for 사용
const gsymbol1 = Symbol.for('id');
const gsymbol2 = Symbol.for('id');
console.log(gsymbol1 == gsymbol2); // true
// symbol출력시 항상 description으로 변환해서 출력해야함
// console.log(`value: ${symbol1}, type: ${symbol1}`); // error
console.log(`value: ${symbol1.description}, type: ${typeof symbol1}`); // 정상 출력
object
- real-life objects, data structure
const raccoon = { name: 'raccoon', age: 26 };
// const 로 선언된 raccoon의 경우 변수이름을 바꿀수는 없지만 객체의 key에 접근하여 value를 바꿀수 있음
raccoon.age = 21;
JavaScript - Dynamic typing: dynamically typed language (Need not defining type)
- c or java are statically typed language (Need defining type)
- type에 대한 정의가 필요 없어 유연하여 프로토 타입을 빠르게 만들수 있지만 큰 규모의 경우 오류가 생길 위험이 있음
- 특이한게,
숫자형태의 스트링
을 자기가 알아서 상황에 맞게 인식함
let text = 'hello';
console.log(text.charAt(0)); // h (인덱싱)
console.log(`value: ${text}, type: ${typeof text}`);
text = 1;
console.log(`value: ${text}, type: ${typeof text}`); // 자동으로 type이 바뀜
text = '7' + 5;
console.log(`value: ${text}, type: ${typeof text}`); // 자동으로 int를 string으로 인식하여 바꿈
text = '8' / '2';
console.log(`value: ${text}, type: ${typeof text}`); // 자동으로 string을 int로 인식하여 값을 도출
// console.log(text.charAt(0)); // string인줄 알고 인덱싱 하였으나 어느순간 number로 바뀌어 runtime error발생
// 그래서 TS 가 나옴