2021-11-11(목) 4일차

Jeongyun Heo·2021년 11월 11일
0

넓은 의미에서 메모리를 차지하면 객체

todo리스트

브라우저쪽에서 자바스크립트를 어떻게 써야 되나

키오스크, 맛집
다다음주 월요일 화요일 이때 진행

const가 안전
const가 조금 더 빠르긴 함
안전하게 사용하는 게 목적

annotation
요즘에는 게터 세터 선언 안 함

converting

데이터 / 로직
데이터 안에 데이터를 가지는 게 대부분 구조를 가짐
구조를 어떻게 표현하느냐에 따라 달라짐
대부분의 데이터는 하나로 구성되는 게 아니라 하나 이상으로 구성된다
넓은 의미로 보자면 3가지
1. 클래스 기반 객체 지향 언어
2. 프로토타입 기반 객체 지향 언어 : 자바스크립트
3. 기타 ...

객체 광의(넓은 의미) : 메모리를 차지하면 객체다.

인스턴스
오브젝트
통틀어서 오브젝트라고 부름

객체 좁은 의미 : 클래스 라든지 기타 방식으로 만들어진 애들
자바에서는 그런 애들을 '인스턴스'라고 함

객체(인스턴스)

3가지 방법
객체 리터럴 / 프로토 타입 / 클래스

키-값 => 묶는 거
파이썬에서는 딕셔너리
자바에서는 맵

why? 왜 묶는냐
흩어지고 싶지 아는 거. 비닐봉지처럼 분류해서 정리해놓은 거 같은 느낌. 데이터가 흩어지는 게 싫은 거. 의미를 모아서 더 큰 의미를 만드는 거. 단위 같은 거를 만드는 거.

햄버거 가게 주문 생각해보자
주문 안에는 주문 항목이 있는 거
주문 항목은 두 가지로 구성되어 있다. 1. 메뉴, 2. 수량
주문 항목은 여러 개임. (치즈버거, 치킨버거 등등)
윈도우 폴더에서 많이 본 구조.
우리는 계속 정보를 구조화 시키면서 살아온 거.
모든 정보는 구조를 가진다.

자바 같은 경우는 구조체(클래스)를 만들어줘야 됨
VO / DTO / Entity
클래스를 만들 때도 의미를 부여해서 만듦
통일화 시키는 방법

what?

how? 어떻게 묶어서 어떻게 쓰는가

로직을 묶는 방법 = 함수

패러다임 쉬프트
패러다임이 완전히 쉬프트 됨

머신러닝 알고리즘은 두 가지로 나뉜다
분류와 예측
K-NN 알고리즘은 '분류'

자바에서는 무조건 클래스로 만들어야 됨
상속

피자가게 메뉴판
피자 - 불고기 피자
피자 - 치즈 피자
상속?

기준이 없음

객체 - 속성(attribute/property) - 속성값(attribute value/property value)

HTML에서 div를 { }라고 생각하면 됨

<div>
    <div>
        <div>
            <h1 class = "aa" id = "bb">Hello</h1>
        </div>
    </div>
</div>

class, id 얘네도 attribute라고 함. 얘네도 객체임.

브라우저가 어떻게 동작하는지

html도 구조가 있음
그 안에 특정한 애가 있고 그 안에 속성이 있고 속성값이 있음
그게 바로 객체와 속성과 속성값
자바스크립트도 문자열
식(expression)과 문(statement)
메모리 상에 올리고 처리
html도 문자
브라우저도 처리
메모리 상에 뭔가를 만들어서 올리겠죠
메모리 상에 올릴 때 구조가 필요함
우리가 만든 트리 구조

=> 모든 데이터는 구조를 가진다.

구조를 그대로 써먹는 방식이 있고
수학적으로 변형해서 쓰는 방법
관계라는 걸 이용해서 변형
그게 관계형 데이터베이스

배열 안에 객체 씀
메모리 구조로 보면 거의 똑같

타이타닉의 생존자 분석
이 사람이 살았을까

머신러닝 → 딥러닝

정렬의 방식
분할 정복
퀵 정렬

우리가 쓰는 건 머지 정렬 (Merge 정렬)

공역 치역

화살표 함수

f(x) = y

두 개의 데이터를 넣어서 숫자가 나오는

모든 함수는 리턴을 한다. 뭔가 반환을 한다.
모든 함수는 결과가 있다.

movies.sort((a, b) => {
  //
})

f(x + y) = 1

movies.sort((a, b) => 1) // 1 리턴

중괄호가 없으면 무조건 리턴돼서 return 키워드 안 써줘도 됨

안에 코드를 여러 줄을 작성하고 싶을 때 중괄호{ }를 쓴다.
중괄호를 쓴 경우 return 이라는 키워드를 반드시 써야 한다.

movies.sort((a, b) => {
    return 1 // return 필수
})

a랑 b는 영화

a - b = 음수 : 앞으로 갈 건지 (a가 b보다 작다)
a - b = 양수 : 뒤로 갈 건지 (a가 b보다 크다)
a - b = 0 : 제자리에 있을 건지 (a와 b가 같다)

disA - disB > 0
A가 더 멀다는 뜻
그럼 뒤로 가야지

const target = {action: 10, kiss: 10} // 반지의 제왕
readline-sync로 action, kiss 받기

category 카운팅 해야 됨 (개수)

k 값은 3

가장 가까운 거 3개

스테레오 타입 (흑, 백)

모노 타입

const movies = [
    {action: 12, kiss: 2, category: 'A'},
    {action: 2, kiss: 14, category: 'M'},
    {action: 7, kiss: 2, category: 'A'},
    {action: 2, kiss: 10, category: 'M'},
    {action: 6, kiss: 15, category: 'M'},
]

const target = {action: 9, kiss: 3} // 반지의 제왕

movies.sort((a, b) => {
    const disA =  Math.sqrt(Math.pow(a.action - target.action, 2) + Math.pow(a.kiss - target.kiss, 2))
    const disB =  Math.sqrt(Math.pow(b.action - target.action, 2) + Math.pow(b.kiss - target.kiss, 2))
    return disA - disB > 0 ? 1 : -1
})

console.log(movies)

const knum = 3
const result = {actionCount: 0, kissCount: 0}

for (let i = 0; i < knum; i++) {
    const movie = movies[i]
    if (movie.category === 'A') {
        result.actionCount += 1
    } else if (movie.category === 'M') {
        result.kissCount += 1
    }
}

console.log(result)

const str = result.actionCount > result.kissCount ? '액션' : '멜로'

console.log(`이 영화는 ${str} 영화인 거 같습니다.`)

const readlineSync = require('readline-sync');

readline-sync 이용해서 액션신, 키스신 입력받기 ↓

const readlineSync = require('readline-sync');

const movies = [
    {action: 12, kiss: 2, category: 'A'},
    {action: 2, kiss: 14, category: 'M'},
    {action: 7, kiss: 2, category: 'A'},
    {action: 2, kiss: 10, category: 'M'},
    {action: 6, kiss: 15, category: 'M'},
]

const actionCut = parseInt(readlineSync.question("action : "))
const kissCut = parseInt(readlineSync.question("kiss : "))

const target = {action: actionCut, kiss: kissCut}

// const target = {action: 9, kiss: 3} // 반지의 제왕

movies.sort((a, b) => {
    const disA =  Math.sqrt(Math.pow(a.action - target.action, 2) + Math.pow(a.kiss - target.kiss, 2))
    const disB =  Math.sqrt(Math.pow(b.action - target.action, 2) + Math.pow(b.kiss - target.kiss, 2))
    return disA - disB > 0 ? 1 : -1
})

console.log(movies)

const knum = 3
const result = {actionCount: 0, kissCount: 0}

for (let i = 0; i < knum; i++) {
    const movie = movies[i]
    if (movie.category === 'A') {
        result.actionConut += 1
    } else if (movie.category === 'M') {
        result.kissConut += 1
    }
}

console.log(result)

const str = result.actionConut > result.kissConut ? '액션' : '멜로'

console.log(`이 영화는 ${str} 영화인 거 같습니다.`)

함수

패러다임

시작점

어떤 문제를 봤을 때 내가 이걸 어떻게 생각하면서 풀어나가느냐

자본주의 라는 패러다임
자본으로 환산

절차 지향적 패러다임 (요리책 같은 거)
요리책 비슷함
재료가 있고 순서가 있음
데이터 재료와 로직을 순차적으로 풀어나감
절차지향적 패러다임의 문제점
재사용을 못 함

함수로 만들어놓으면
함수형 패러다임
절차지향적 패러다임이랑 시작하는 위치가 다름. 시작점 자체가 다름.

주어진 데이터가 뭔지 봄

함수형 패러다임은 코어로직을 먼저 봄
로직 중에 코어
그 안에 필요한 덩어리 로직
원의 넓이
넓이의 차
함수형 주의자들이 제일 먼저 하려는 거
이 로직부터 구성
메인 main 가장 중요한 함수
함수형 주의자
모든 함수는 3가지 형태로 구성된다.
이름, 입력값(parameter, arguments), 출력값(반환값)
자바 같은 언어가 문제가 생김
결과를 반환할 게 없으면?
땜빵이 필요함
void 키워드
void는 기본자료형임
반환값
억지로 만든 키워드가 void
void는 사실 기본 자료형에 속함
void는 메모리 공간을 차지하지 않음
void는 값을 assign할 수 없음
메모리 할당 못
로직을 처리하려고
그 안에 식과 문
여러 개의 식과 문이 들어가서
집합이 나올 수 밖에 없음
브레이스로 묶었음
이 브레이스는 특별한 브레이스
그래서 앞에 키워드
function 이라는 키워드

function 함수명(파라미터) {
  //
  return ;
}

함수와 변수가 다른 게 아니다!

return 뒤에 아무것도 없어도 됨

return이 반환을 하기 위해서 쓰는 게 아니라는 거

return의 의미 : 실행의 제어권을 반납한다.

역컴파일 하면 return문이 들어감

ge = greater than

return 이라는 키워드가 뭔가를 반환하는 게 아니라 나 이거 끝났다는 거

반복문 goto

return이라는 키워드는 나는 끝났어

JVM은 우리가 짠 코드를 코드를 최적화시킨 상태

전부 다 함수로 분석

자바는 클래스부터 만들어야 되고

함수형 주의자들은 함수부터 만들어야 됨

함수들 로직이 나오면 순서도

함수형 주의자들이

어디가 시작점인지 알 수 없어

그래서 만들어진 게 main 함수

자바는 모든 걸 다 클래스 단위로 로딩

main함수를 실행하기 위해서 껍데기를 만들어야함

public class Main

class 이름 자체를 Main으로 함

Main 클래스만 찾으면 됨

클래스로 로딩

함수 하나 실행시켜

자바스크립트는 클래스 필요 없이 바로 함수 실행 가능

그냥 바로 함수 선언하고 실행하면 됨

함수도 변수와 같음
함수도 그 안에 코드들이 있음
실행을 하기 위한 코드들

함수도 객체임

중괄호 (집합)

식과 문을 모아놓았을 뿐

메모리 상에서 처리할 때 특별하게 처리해야 됨
function
파이썬에서는 def

배열
arr
배열 안에 데이터 들어감

함수도 이름이 있음

함수이름 = 변수이름

함수이름이라는 게 변수임

결국엔 똑같이 포인터 역할

함수를 호출하면 별도의 메모리에서 실행을 시킴

function getArea() {
    console.log("-------------")
    console.log("-------------")
    console.log("-------------")
}

const v1 = getArea

console.log(v1)
console.log(getArea)

getArea()
v1()

별도의 메모리 공간을 잡아서 식과 문을 별도의 메모리 공간을 할당하고 실행하게 됨
재사용하려고 만든거니까
별도의 메모리 공간에서 실행
함수 스택(stack)이라고 한다
함수를 실행하면 메모리 공간

자바는 조금 다름

pubic class Main {
    public static int add(int a, int b) {
        return a + b;
    }

변수 3개가 필요한 거 (int a, int b, int xxx ←이름 없는 변수)
함수 실행할 때만 잠깐 쓰이고 안 쓸 거 : 지역변수

add() ← 함수를 호출할 때는 괄호( )를 붙인다.
add ← 괄호( ) 안 붙이면 그냥 포인터(리모컨) 말하는 거

별도의 메모리 공간
add를 실행했을 때 메모리 공간
자바는 변수를 새로 만들 때만 타입이 필요

a + b
연산자
자바는 변수에 담거나 바로 소비하거나

int a = x
int b = y
int xxx = a + b

나 끝났어

메모리 공간이 없어짐
함수을 실행하는 동안만 살아있고 함수의 실행이 끝나면 없어짐

arr.length
그게 더 빠르니까
배열은 크기가 고정

str.length()

지역변수 : 함수 안에 선언되는 변수
함수가 끝나면 같이 사라지는 변수

그렇기 때문에
f(x) = y가
항상 동일하게 실행되고 동일하게 끝나야 되니까
값을 저장 안 하고 없애버리는 거

자바 변수 3개
1. 클래스 변수
2. 인스턴스 변수
3. 지역 변수

함수 : 로직을 위해 코드(문/식)를 묶어둔 덩어리
변수로 할당 → 함수이름
함수는 ()로 실행 → 메모리 공간 → 필요한 변수 생성 → 지역 변수 (local variable)

사실 변수랑 함수랑 같다

자바스크립트는 이걸 그대로 허용

1급 객체 (first class object)

자바스크립트에서 함수는 변수가 들어갈 수 있는 모든 곳에 들어갈 수 있다.

함수는 코드의 집합을 나타내는 자료형이다.
함수를 코드의 집합이라고 말하는 이유는 중괄호{ } 내부에 코드를 넣기 때문이다.
함수의 자료형은 function이다.

다른 프로그래밍 언어는 함수를 지정된 위치에서 만들어야 하지만
자바스크립트는 '함수도 하나의 자료'라는 개념을 가지고 있어서 중간에 만들 수 있다.

자바스크립트는 함수도 하나의 자료형이므로 매개변수로 전달할 수 있다.
이렇게 매개변수로 전달하는 함수를 콜백(callback) 함수라고 한다.

함수를 쓰면 나쁜 점 : 메모리

function getArea(radius) {
    const area = Math.pow(radius, 2) * Math.PI
    return area
}

function getTotal(r1, r2) {
    return Math.abs(getArea(r1) - getArea(r2))
}

console.log(getTotal(10, 20))

함수 안에서 함수를 호출할 수 있구나

// 함수 선언문
function calcHour(hour) {
    const result = (360 / 12) * (hour % 12)
    return result
}
// 얘는 문으로 처리됨

지역변수 2개 생김 (hour, result)

나 끝났는데 result 남기고 죽을 거야

const calcMin = function(min) {
    
}
// 얘는 식으로 처리됨

리액트
const Sample = () => 코드

// 분침의 각도
const calcMin = (min) => {

}
// 화살표 함수

하나일 때는 괄호 안 해도 됨

화살표 함수

// 분침의 각도
const calcMin = min => {

}
// 화살표 함수

중괄호도 생략이 가능함

const calcMin = min => 10
// 분침의 각도
const calcMin = (min) => (360 / 60) * min

변수가 선언될 수 있는 모든 곳에 함수가 선언될 수 있다.

자바에서는 메서드 안에서 메서드를 호출할 수 없다.

버튼을 클릭하면 동작하는 것도 다 함수

더 큰 함수

Math.random()
Math.pow()

이거를 잘 조합하면 함수 하나로 끝낼 수 있을 거 같아
3개를 감싸는 함수를 만들면 됨

function calcTotal(hourValue, minValue) {
    function calcHour(hour) {
        // 시침의 각도 ---> 입력 시: 12, 출력: 각도
        const result = (360 / 12) * (hour % 12)
        return result
    }

    // 분침의 각도
    const calcMin = (min) => (360 / 60) * min

    // 분에 따른 시침의 추가적인 이동
    // 1분에 0.5도
    function getExtra (min) {
        return ((360 / 12) / 60) * min
    }

    return (calcHour(hourValue) + getExtra(minValue)) - calcMin(minValue)
}

// 12시 38분
console.log(calcTotal(12, 38))

음수가 나오는 경우도 있으니까 Math.abs() 사용해서 절댓값으로 받기

function calcTotal(hourValue, minValue) {
    function calcHour(hour) {
        // 시침의 각도 ---> 입력 시: 12, 출력: 각도
        const result = (360 / 12) * (hour % 12)
        return result
    }

    // 분침의 각도
    const calcMin = (min) => (360 / 60) * min

    // 분에 따른 시침의 추가적인 이동
    // 1분에 0.5도
    function getExtra (min) {
        return ((360 / 12) / 60) * min
    }

    const result = Math.abs((calcHour(hourValue) + getExtra(minValue)) - calcMin(minValue))

    return result > 180 ? 360 - result : result
}

// 12시 38분
console.log(calcTotal(12, 38))

음수면 양수로 만들고 180도가 넘으면 360에서 뺀 값을 반환

하나로 뭉친다는 느낌

자바는 클래스 단위

public class Main {
    public static int add(int a, int b) {return a + b}
    
    public static void main(String[] args) {
    
        int result = Main.add(10, 20);
    }
}

컴파일하면 클래스 파일이 만들어짐
코드는 파일에 있음
코드를 메모리상으로 끌어올려야 됨

classLoader

add가 가리키는 메모리 블록
main이 가리키는 메모리 블록

자바의 메모리는 크게 두 가지로 나눠지는 거

함수를 실행하면 메모리 공간이 새로 잡힘
타입이 앞에 있으면 새로 만들어지는 거
args 라는 변수가 새로 생김
args = xxx

Main.add() ← jump

main이 끝나기 전에 add를 실행

static 키워드 : 클래스에 달라붙음

스택
그 위에 쌓아서 실행

main에서 또 실행하고 또 실행하고 하면 넘침

public class Main {
    public static int add(int a, int b) {return a + b}
    
    public static void main(String[] args) {
    
        int result = add(10, 20);
    }
}

같은 클래스 내에서는 앞에 Main. 안 붙이고 add()만 써도 됨

int result = add(10, 20);

add ← 클래스 메서드

자바스크립트에서는 함수

함수 : 로직을 처리하는 단위 (문, 식이 들어감)

함수 이름이 있어야 함 (그래야 나중에 다시 불러서 사용)

{ } 함수를 위한 브레이스

function

로직은 동사
함수는 동사로 적는다.

절차지향
위에서 썼던 변수명을 밑에서 계속 씀

함수형
함수부터 생각
이 데이터가 뭔지도 모르는데 함수부터 ㅉ
변수 가정하고 코딩함

정해진 숫자만큼 출력하는 함수

printNums()

숫자 2개도 의미를 주는 게

from, to
start, end

목적이 확실
번호를 출력하는 게 역할

반환값이 있는지 없는지 매번 확인하고 변수를 만드는 것보다
일관성 있게 변수 하나 만들어 놓는다

function printNums (start, end) {
    // 몸통
    for (let i = start; i <= end; i++) {
        console.log(i)
    }
}

const result = printNums(1, 10)
console.log(result) // undefined

undefined : 변수는 있는데 값이 assign 된 적 없다

public class My11Util {

My11Util.getMaxInArray(arr);

어떻게 하면 자바스크립트를 가져다 쓸까

const readlineSync = require('readline-sync');

웹페이지 안에서 제어하기 위해

자바스크립트는 1급 객체다.
자바스크립트의 함수는 변수처럼 쓰인다.
일반적인 변수처럼 선언이 가능하다.
다른 함수의 파라미터가 될 수 있다.
다른 함수의 리턴값이 될 수 있다.

자바스크립트에서는 파라미터가 유연하다.

자바에서는 파라미터의 개수가 맞아야 호출이 가능하다.

function printNames(str1, str2, str3) {
    console.log(str1)
    console.log(str2)
    console.log(str3)
}

printNames()
printNames("AAA")
printNames("AAA", "BBB")
printNames("AAA", "BBB", "CCC")

printNames(str1, str2, str3) ← parameter가 3개
파라미터가 3개라는 건 변수가 3개 만들어진다는 거
printNames() ← arguments 없이 함수를 호출
변수가 3개가 선언되었지만 값이 할당된 적이 없다
undefined로 출력됨

자바스크립트에서는 매개변수에 기본값을 미리 지정할 수 있다.
기본 매개변수 : 매개변수에 기본값을 지정

자바에는 파라미터 기본값 기능이 없다.

function printNames(str1, str2 = "111", str3 = "222") {
    console.log(str1)
    console.log(str2)
    console.log(str3)
}

printNames()
printNames("AAA")
printNames("AAA", "BBB")
printNames("AAA", "BBB", "CCC")

함수를 파라미터로 던질 수 있다. (콜백 함수)

계산기

function calc(a, b, fn) {          // a, b는 숫자, fn은 함수
    console.log("A: " + a)
    console.log("B: " + b)
}

if (fn === "+")
else if (fn === "-")
else if (fn === "*")
else if (fn === "/")

4개에서 끝나는 게 아니라

else if가 수백개 들어가야 됨

fn ← 이 파라미터 함수도 파라미터가 있고 리턴타입이 있음

function calc(a, b, fn) {         // a, b는 숫자, fn은 함수
    console.log("A: " + a)
    console.log("B: " + b)

    const result = fn(a + 1, b + 1)  // 콜백 함수 호출

    return result
}

console.log(calc(10, 20, (x, y) => x + y))

console.log(calc(10, 20, (x, y) => x - y))
A: 10
B: 20
32
A: 10
B: 20
-10

로직을 변경할 수 있게 됨
자바는 이런 게 잘 안 됨
가장 대표적인 케이스 : 버튼을 클릭했을 때 어떻게 할 거냐 (이벤트 핸들링)

파라미터로 함수를 전달

자바스크립트 면접 문제
1번 호이스팅
2번 클로저

매칭

동일한 입력값에 동일
기존의 데이터에 영향을 받음
사이드 이펙트

로직을 재사용하기 위해

함수 썼을 때 문제점

상태가 영향을 미친다

데이터와 함수를 결합한 존재가 있으면 좋겠는데
자바에서는 객체

static 붙으면 무조건 클래스에 달라붙
static이 없으면 객체에 달라붙음

public void showCar1Info() {
데이터와 로직을 결합시킨 거 같음

객체 리터럴
로직은 함수
덩어리로 묶으려고
데이터가 흩어지는 게 싫은 거

데이터 가지고 할 수 있는
자바에서는 클래스

자바의 클래스는 데이터와 로직 합친 거

자바스크립트는

new를 이용해서

p1이 가리키는 메모리 공간이 있는 거고
p2가 가리키는 메모리 공간이 있는 거

add 가 가지고 있는 메모리 공간에서만 돌아가는 거

구조화된 데이터
데이터랑 로직이랑 같이 유지해야 될
바로 객체지향

함수를 저장한 레코드(메모리)

클로저는 돼지저금통

원래 지역변수는 함수가 종료되면 없어져야 되는데 return 함수에서 total을 사용

클로저 : 감춰진 참조

감춰져 있는 참조

특별한 조치를 한 적 없음

죽고 싶은데 죽지 못하는 애

리턴값으로 함수를 쓸 수 있다. 클로저가 될 수 있다.

브라우저에서 동작하는 자바스크립트

브라우저는 독특한 도구

브라우저는 뷰어

데이터가 있어야
데이터를 제공해주는 게 서버 Server

이 데이터는 어떤 데이터일까요
문자열

내용물(HTML) / 스타일(CSS) / 제어(JS)

웹의 초창기
브라우저가 간단했음

자바스크립트
순수한 데이터와 스타일링과 로직을 완전히 따로 따로 만들어서
처리할 수 있는 엔진을 각각 가짐
브라우저 내부에는 3개의 엔진이 돌아감

데이터는 구조를 가짐
그 구조가 바로 HTML
HTML 눈에 보이는 태그
눈에 보이지 않은 태그도 있음
HTML이 화면 보여주는 애가 아님
구조를 표현한 언어
Markup Language

HTML은 왜 프로그래밍 언어가 아닐까?

브라우저랑 약속
약속대로 보내줘야
스펙
html이 그래서 스펙
구분
script

    <body>
    <script>
        console.log("AAAAAAAAAAA")
        alert("AAA")
    </script>

script를 만남
이거는 스크립튼데?
스크립트 엔진한테 던져줌
자바스크립트는 이 부분을 실행함
자바스크립트가 2번 읽는다
처음에는 문을 처리하고 그 다음 실행한다

alert : 지금은 자바스크립트에서 권장하지 않음

alert를 만나면 브라우저는 동작을 멈춤

결국엔 브라우저가 받는건 이런 데이터
이 데이터는 구조가 있다
이 데이터 안에 스크립트가 있다
스크립트를 만나면 스크립트 엔진한테 준다
스크립트를 실행한다
alert를 만나면 브라우저는 동작을 멈춤

script 태그의 위치 하나도 어디에 놓을지도 고민하면서 짜야 됨

출력결과는 개발자 도구 - Console에서 확인할 수 있다.

0개의 댓글