본문 바로가기

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())
  • 둘다 확인이 가능한 이유 : 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 가 나옴