[DAY 01] JS 주요 문법(1)

38714 단어 TIL데브코스TIL

[1] JavaScript

[1-1] JavaScript의 탄생 배경

  1. 팀 버너스리가 최초의 브라우저 개발
  2. 넷 스케이프가 최초의 상용 브라우저인 Navigator 출시
    • 이때의 웹은 HTML로만 이루어져 정적인 기능만 제공
    • 이는 링크가 존재하는 워드 문서와 큰 차이가 없었음
  3. 프로그래밍 언어를 브라우저에 내장
  4. 브렌던 아이크는 10일만에 Mocha라는 언어를 만들어내고, LiveScript로 이름 변경
  5. Java가 큰 인기를 끌어, 마케팅 효과를 위해 JavaScript로 이름 변경

[1-2] JavaScript로 할 수 있는 것

  • 초창기: 브라우저에서 단순한 DOM조작, alert, confirm 등을 사용하기 위함
  • 현재: 복잡한 UI, 지도, 유튜브, 서버 개발, 모바일 앱 개발 등 가능
    • 서버 개발: node.js, NestJs, Express, ⋯
    • 앱 개발: React Native, NativeScript, Cordva, ⋯
    • 프론트엔드 개발: jQuery, Backbone.js, React, Vue, Angular, i18n, WebRTC, ⋯



[2] 브라우저의 동작 원리

  • 통신: 서버와 브라우저의 통신
    • 브라우저가 서버로 요청을 보내면, 서버는 요청에 따라 특정 값을 응답
    • 이 요청은 한 번에 하나씩할 수도, 동시에 할 수도 있다.
  • 렌더링: DOM이라는 객체를 화면에 그리는 것
    • DOM: 통신을 통해 받은 HTML을 브라우저가 읽어서 생성됨
    • DOM은 트리구조의 특징
  • 스크립트 실행: 이를 통해 동적인 화면을 구성할 수 있다.



[3] 프론트엔드 개발자의 역할

  • 프론트엔드 개발자: 브라우저에서 동작하는 UI 개발
  • 개발 능력뿐만 아니라, 다른 직군과 협업을 위한 소통 능력이 아주 중요
  • 고객과 맞닿아있는 직군이기 때문에 기획, 마케팅 영역까지
  • 핵심역량 6가지
    • 커뮤니케이션
    • UI
    • 네트워크
    • 보안
    • 브라우저
    • 디자인
  • 컴퓨터 과학 무시, CSS 안하기, 코더가 되는 것 → 절대❌



[4] 변수, 상수, 자료형, 메모리

[4-1] 변수

  • var: ES6 이전의 키워드
  • let: ES6 이후 출시

[4-2] 상수

  • const

[4-3] 자료형

  • Number
  • String
  • Boolean: True or False
  • Object
  • Array
  • Function
  • Undefined: 선언 후, 값 대입X
  • Null: 변수가 비어있음

[4-4] 메모리

  • 할당 → 사용 → 해제
  • Garbage Collector를 통해 메모리 정리
    • Garbage Collection이라는 자동 메모리 관리 알고리즘을 통해 만들어진 객체
    • 사용하지 않는 메모리를 해제하는 역할
    • 이것 덕분에 메모리에 대해 큰 신경 없이 편리하게 사용 가능

[4-5] 메모리 심화

  • 힙에는 참조타입, 콜스택에는 원시타입이 들어간다.
  • Mark and Sweep Algorithm: 닿을 수 없는 주소를 더 이상 필요없는 주소로 정의하고 지우는 알고리즘



[5] 표현식과 연산자

[5-1] 표현식

  • 어떠한 결과 값으로 계산되는 식
  • 원시값(숫자, 문자열, 논리값), 변수, 상수, 함수 호출 등으로 조합할 수 있다.

[5-2] 연산자

  • 할당 연산자: 오른쪽 표현식을 왼쪽 피연산자 값에 할당
  • 비교 연산자: 좌측 피연산자와 우측 피연산자를 비교, true or false 반환
  • 산술 연산자: 덧셈, 뺄셈, 나눗셈 수행, Number 반환
  • 비트 연산자: 비트를 직접 조작
  • 논리 연산자: Boolean 통해 참과 거짓을 검증
  • 삼항 연산자: 조건 ? 참: 거짓
  • 관계 연산자: 객체에 속성이 있는지 확인
  • typeof: 피연산자의 타입 반환, 문자열로 반환



[6] 흐름제어

[6-1] Control Flow

  • Goto
  • If / Then / Else
    • 거짓으로 판단: false, undefined, null, 0, NaN, ′′
  • Switch / Case
  • For / While

[6-2] Data Flow

  • Stateless
  • Recursion
  • Pipe



[7] 배열과 객체

[7-1] 배열

  • 배열 생성
const arr1 = new Array();
const arr2 = [];
const arr3 = [1, 2, 3, 4, 5];
const arr4 = new Array(5); // 5개의 빈 요소
const arr5 = new Array(5).fill(1); // [1, 1, 1, 1, 1]
const arr6 = Array.from(Array(5), function (v, k) { // [1, 2, 3, 4, 5]
	retrun k + 1;
});
  • length
const arr = [1, 2, 3, 4, 5];
arr.length = 3; // [1, 2, 3] // 권장하지 않음
  • 배열 관련 함수: join, reverse, concat
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [6, 7, 8];
arr1.join(", "); // 1, 2, 3, 4, 5
arr1.reverse(); // [5, 4, 3, 2, 1] // 원본 배열에 영향
arr1.concat(arr2); // [1, 2, 3, 4, 5, 6, 7, 8]
  • 배열의 마지막 인덱스에 요소 추가/삭제하는 함수: push, pop
const arr = [1, 2, 3];
arr.push(4); // [1, 2, 3, 4]
arr.push(5, 6, 7); // [1, 2, 3, 4, 5, 6, 7]
arr.pop(); // 7 // 삭제한 요소를 반환
arr.pop(); // 6
  • 배열의 첫 인덱스에 요소 추가/삭제하는 함수: unshift, shift
const arr = [1, 2, 3, 4, 5]
arr.shift(); // 1
arr.shift(); // 2
arr.unshift(10); // [10, 3, 4, 5]
  • 배열 원소 중간에 접근: slice, splice
const arr = [1, 2, 3, 4, 5, 6];

//2번 인덱스부터 3번 인덱스까지 자르기
arr.slice(2,4); // [3, 4] // 원본 배열에 영향X

//2번 인덱스부터 2개의 요소 삭제
arr.splice(2,2); // [1, 2, 5, 6] // 원본 배열에 영향
  • 배열 순회: for of 추천
const arr = [1, 2, 3, 4, 5, 6];

for (let i = 0; i < 5; i += 1) {
	console.log(arr[i]);
}

// 이렇게 사용하기!
for (const item of arr) {
	console.log(item);
}
  • 배열은 객체처럼 사용 가능 (배열 타입과 객체 타입은 동일)
const arr = [1, 2, 3];
arr['key] = "value"; // 권장하지 않는 방법
console.log(arr); // [1, 2, 3, key: 'value']
arr.length; // 3 // key 값이 추가되어도 길이는 불변
// 배열은 JS에서 특수한 객체이기 때문에 배열의 길이는 내부적으로 관리

[7-2] 객체

  • 객체 생성
const obj1 = new Object();
const obj2 = {};
const obj3 = { name: "김지은", age: "스물셋" };
  • 객체의 값 추가/삭제
// 추가
const obj = { name: "김지은", age: "스물셋" };
obj["email"] = "[email protected]";
// { name: "김지은", age: "스물셋", email: '[email protected]' }
obj.phone = "01027143094";
// { name: "김지은", age: "스물셋", email: '[email protected]', phone: '01027143094' }

// 삭제
delete obj.phone; // { name: "김지은", age: "스물셋", email: '[email protected]' }
  • key가 있는지 확인: in
const obj = { name: "김지은", age: "스물셋" };
console.log("email" in obj); // false
console.log("name" in obj); // true
  • key, value 집합 알아내기: keys, values
const obj = { name: "김지은", age: "스물셋" };
console.log(Object.keys(obj)); // ['name', 'age']
console.log(Object.values(obj)); // ['김지은', '스물셋']
  • 객체 순회하기: for in
const obj = { name: "김지은", age: "스물셋", phone: "01027143094" };

for (const key in obj) {
	console.log(key, obj[key]);
}



[8] 스코프와 클로저

[8-1] 스코프

  • 유효 범위라고도 부르며, 변수가 어느 범위까지 참조되는 지를 뜻한다.
  • Global Scope(전역 스코프), Local Scope(지역 스코프)
const a = 5; // Global Scope
{
	const b = 3; // Local Scope
	console.log(a, b); // 5 3
}
console.log(a, b); // Error
  • 여기에서 const가 아닌 var를 사용하면, 호이스팅 되어 변수 선언이 상단으로 올라가버려, 개발자가 예상치 못한 오류가 생길 수 있다.

[8-2] 클로저

  • 함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법
    • 닫힘, 폐쇄라는 뜻처럼 더 이상 외부에서 접근 불가한 영역을 클로저를 통해 접근 가능
function makeGreeting(name) {
	const greeting = "Hello, "; // 지역스코프라서 함수가 종료되면 메모리에서 사라진다.

	return function () {
		console.log(greeting + name);
	};
}

const world = makeGreeting("World!");
const jieun = makeGreeting("Ji-Eun");

// 그런데 실행 시점에 greeting이 살아있다!
world();
jieun(); 

[8-3] 은닉화

  • 클로저를 이용하여 내부 변수와 함수를 숨길 수 있다.
    • 클로저를 유용하게 사용할 수 있는 방법!
function Counter() {
	let privateCounter = 0
	function changeBy(val){
		privateCounter += val
	}
	return {
		increment: function() {
			changeBy(1)
		},
		decrement: function() {
			changeBy(-1)
		},
		value: function() {
			return privateCounter
		},
	}
}

const counter = Counter();
console.log(counter.value()); // 0
counter.increment();
console.log(counter.value()); // 1
counter.dncrement();
console.log(counter.value()); // 0
  • 위 코드의 Counter 함수를 보면, 변수와 내부 함수는 외부에서 접근 불가
  • 따라서 반환된 함수로만 값을 조작할 수 있게 되어 개발자의 실수를 줄일 수 있다.

[8-4] 클로저를 잘 알아야 하는 이유

  • 유용하게 사용하기 < 알기 힘든 버그를 잘 수정하기
function counting() {
	let i = 0;
	for (i = 0; i < 5; i += 1) {
		setTimeout(function () {
			console.log(i)
		}, i * 1000);
	}
}

counting(); // 5 5 5 5 5 

(당당하게 1 2 3 4 5라고 생각한 나...)

  • setTimeout의 대기시간이 끝나 콜백함수가 실행되는 시점에는 루프가 종료되어 i는 5가 되어 있다.

    • 콜백함수는 클로저이기 때문에 상위 i값을 물어보고, 이미 i값은 5까지 증가했기 때문에 5가 5번 출력되는 것!
  • 해결방법1: 즉시 실행 함수(IIFE) 이용하여 루프마다 클로저 만들기

    • 즉시 실행 함수: 정의되자마자 즉각적으로 실행되는 함수
      function counting() {
        let i = 0;
        for (i = 0; i < 5; i += 1) {
          (function (number) {
            setTimeout(function () {
              console.log(number);
            }, number * 100);
          })(i);
        }
      }
      
      counting();
  • 해결방법2: 블록 스코프로 해결하기(let이용)

    • let은 블록 수준 스코프이기 때문에 매 루프마다 클로저가 생성된다.

    • 매 반복마다 새로운 i가 선언되고, 반복이 끝난 이후의 값으로 초기화된다.

      function counting() {
      	for (let i = 0; i < 5; i += 1) { // for 내부에 let 변수 선언한 것과 동일
      		setTimeout(function () {
      			console.log(i)
      		}, i * 1000);
      	}
      }
      
      counting();

좋은 웹페이지 즐겨찾기