2021-12-16(목) 6주차 4일

Jeongyun Heo·2021년 12월 16일
0

리턴 값이 없는 함수를 console.log로 출력하면?
undefined 나옴

파라미터와 아규먼트

51-자바스크립트 / 13 페이지

파라미터 : 함수가 작업하는 데 사용할 값을 받는 변수

자바스크립트 함수를 호출할 때 아규먼트의 개수는 함수에 정의된 파라미터 개수와 일치하지 않아도 된다. 에러 안 뜸.

parameter : 값을 받는 변수
argument : 함수를 호출할 때 넘겨주는 값

같은 이름의 함수가 동시에 존재할 수 없다. 맨 마지막에 정의된 함수로 됨.
기존 함수를 덮어쓴다.

자바스크립트의 모든 함수에 arguments라는 내장 변수가 존재한다.

Prototype ← '원형'이라는 뜻

생성자, 객체, prototype

51-자바스크립트 / 14 페이지

① new → 빈 객체 생성
빈 객체는 key, value 값을 담는다.
Array()의 조상은 Object()이고
Array 생성자는 내부적으로 Object를 찾아가게 되어 있음
function Array() 내부구조를 보면 첫 번째 문장이 주어진 객체에 대해서 Object()를 제일 먼저 호출한다.

function Array() {
  this.Object();

Array라는 생성자가 작업을 수행하기 전에 먼저 Object라는 생성자가 먼저 작업을 한다. Object라는 생성자를 상속받았다고 표현한다.
Array가 호출되자마자 제일 첫 번째 만나는 문장이 Object를 호출하는 거
① Object 함수에서 변수와 함수 추가
② Object() 함수에서 변수와 함수 추가
③ Array() 함수에서 변수와 함수 추가
이렇게 객체를 초기화 시키는 함수를 "생성자(constructor)"라 부른다.
객체를 초기화 시킨다는 의미는?
객체가 주어진 역할을 하는 데 필요한 변수나 함수를 준비하는 것
프로토타입 : 객체를 초기화시킨 생성자를 가리킨다.
이전 기수가 강의를 들었고 강의가 끝났으면 새 반이 수업을 진행할 수 있도록 수업이라는 업무를 보는 데 필요한 모든 것들을 세팅하는 거
그 함수가 바로 생성자
생성자에 의해 초기화 된 객체
어떤 역할을 수행하는 데 필요한 변수나 함수를 갖고 있는 것을 "객체(object)"라 부른다.

이 객체는 누가 초기화 시켰나요?
[[Prototype]]: Array
아 이 객체는 Array 라는 생성자가 초기화 시켰어요
프로토타입에 이 객체가 어느 생성자가 초기화 시켰는지 나온다

이 객체를 초기화 시킨 게 Array가 아니면 얘는 배열이 아닌 거임
배열과 유사한 애
arguments는 배열이 아니다.

function f5(a) {
	arguments.forEach(function(value) {
		console.log(value);
	})
}

f5(100, 200, 300, 400);
console.log("----------------");

arguments 내장 변수는 Array()로 초기화시킨 배열 객체가 아니기 때문에 forEach()라는 함수가 없다.

함수도 변수와 같이 자동으로 window 객체에 소속된다.

함수 객체

function = object + function body(함수 코드)

var f1;

f1 = function(a) { 
	console.log(a + "님, 안녕!");
};

변수를 만들고 변수 안에 함수를 정의한다.

현재 스크립트 태그가 아닌 다음 스크립트 태그에서 정의한 함수는 호이스팅 대상이 아니다. 호이스팅은 그 script 태그를 실행할 때 수행된다.

할당문은 올라가지 않는다.

제이쿼리가 내부적으로 다 해준다
크로스 브라우저 다 해줌

제이쿼리를 왜 씁니까?
크로스 브라우징 때문에 씁니다.
브라우저에 상관없이 동일하게 사용할 수 있다.

함수 객체 주소를 주고 받는 거
play(plus); ← plus 라는 함수의 주소를 넘기는 거

함수를 넘긴다 → 함수의 주소를 넘긴다

호출 당한 게 아니라 다이렉트로 우리가 호출한 거
파라미터나 변수로 넘겨주는 게 콜백
파라미터로 받은 함수를 호출하는 것이 아니기 때문에 콜백 함수가 아니다.

함수 안에서 함수를 만들어 리턴할 수 있다.

클로저(closure)

http://localhost:8080/javascript/ex03/exam10.html

createInterestCalculator() 함수가 리턴하는 것은 내부에서 정의한 함수의 주소이다.
이렇게 함수 안에서 정의한 함수를 '클로저(closure)'라 부른다.

클로저 : 함수 안에서 정의한 함수

클로저와 로컬 변수

http://localhost:8080/javascript/ex03/exam11-1.html

바깥 함수의 로컬 변수

로컬 변수는 함수 호출이 끝나면 사라진다.

함수 호출이 끝나면 그 함수가 만든 로컬변수도 제거된다.
name, message
message 변수에 있는 값을 출력해!
message라는 변수가 없음
에러 안 남. 잘만 나옴.
이 함수 안에는 message 변수가 없는데 어떻게 출력이 된 거야?
이게 바로 클로저 라는
로컬 변수는 함수가 끝나면 사라짐
자바에서 중첩 클래스를 배울 때도 똑같은 원리임
메소드 호출이 끝나면 사라지는 변수임
파라미터도 로컬 변수임
호출될 때 만들어지고 사라짐
createGreeting 라는 함수가 1000번 호출 되면 로컬 변수는 1000번 만들어지고 1000번 사라짐
바깥 함수의 로컬 변수를 사용할 경우, 클로저 공통 메모리에 복제해둔다.
바깥 함수의 실행이 끝난 후에도 그 값을 사용할 수 있도록 클로저 공통 메모리에 복제해둔다.

사라지기 전에 값을 복제해뒀기 때문에 그 값을 알고 있다는 거
사라지기 전에 count라는 변수의 값을 복제해둔다.

이렇게 클로저를 정의하는 순간 클로저가 사용하는 바깥 함수의 로컬 변수 count는 클로저가 관리하는 별도의 메모리에 복제된다.
따라서 바깥 함수의 실행이 끝나 그 로컬 변수가 사라지더라도 클로저는 복제된 변수를 계속 사용할 수 있다.

같은 클로저인 경우에는 동시에 생성된 클로저인 경우에 변수를 공유한다.
클로저끼리 공유한다.

클로저끼리 복제 변수 공유

// 3) 한 문장만 있을 때는 중괄호를 제거할 수 있다.
// 4) 그 한 문장이 리턴 문장일 경우 return을 생략해야 한다.
// 그리고 문장의 끝을 나타내는 세미콜론을 제거해야 한다.
var f3 = () =>
	"안녕";
;
console.log(f3());

//또는 다음과 같이 익명 함수를 정의하여 바로 아규먼트로 넘길 수 있을 것이다.
play(function(a, b) {return a - b;}); // 함수 주소
play(함수주소)
함수를 호출하는 게 아니라 정의한 거
함수주소를 넘기는 거
play((a, b) => a - b);
//또한 arrow function을 정의하여 바로 아규먼트로 넘길 수 있다.
play((a, b) => a * b); // 함수를 실행하는 게 아니라 정의한 거

함수도 객체이기 때문에 프로퍼티를 추가할 수 있다.

퉁쳐서 프로퍼티라고 부른다.

브라우저에서 많이 쓰는 내장 함수가 있음

web\app\src\main\resources\static\javascript\ex03\exam16-1.html
setTimeout
window 객체에 소속되어 있음

등록

등록하고 호출

window.setInterval(함수, 경과시간);
등록한 순간부터 호출되는 거

clearInterval

16-5로 넘어감
JSON.parse()

"hello"
반드시 소문자 true

{"name" : "nana"}{name: 'nana'}
["apple", "banana"]['apple', 'banana']

싱글 쿼테이션 안 됨. 무조건 더블 쿼테이션.
객체 마지막 프로퍼티 뒤에 콤마 쓰면 안 됨
배열도 마찬가지

이기종 플랫폼 간에 데이터를 주고 받을 때 JSON으로 주고 받는다

자바스크립트 객체 ==변환==> JSON 형식의 문자열

익명 함수를 한 번만 실행하는 경우에는 변수에 담지 말고 바로 호출하는 걸로
그럴 때는 바로 즉시 실행 함수로

8번부터 17번까지

MyList 프로젝트 - ContactController.java

메소드 다루기

• 특정 기능을 수행하는 코드에 대해 메서드로 정의해두면 재사용이 쉽고 코드 유지보수가 쉽다.
• 코드를 메서드로 분리하는 경우
‐ 유사한 코드가 여러 곳에서 중복 사용될 때
‐ 코드의 기능을 명확하게 설명하고 싶을 때

중복 코드를 분리하여 메소드로 정의한다.

CSV(comma-separated values)

CSV : data를 구성하는 필드를 콤마로 구분한 데이터 형식

comma-separated values
comma-separated variables

record = row = entity = object
column = field = attribute

한 사람의 연락처 정보를 문자열로 만드는 코드를 메서드로 분리한다.

ContactController.createCSV()

  String createCSV(String name, String email, String tel, String company) {
    return name + "," + email + "," + tel + "," + company;
  }

전↓

  @RequestMapping("/contact/add")
  public Object add(String name, String email, String tel, String company) {
    String contact = name + "," + email + "," + tel + "," + company;
    contacts[size++] = contact;
    return size;
  }

후↓

  @RequestMapping("/contact/add")
  public Object add(String name, String email, String tel, String company) {
    contacts[size++] = createCSV(name, email, tel, company);
    return size;
  }

전↓

  @RequestMapping("/contact/update")
  public Object update(String name, String email, String tel, String company) {
    String contact = name + "," + email + "," + tel + "," + company;
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        contacts[i] = contact;
        return 1;
      }
    }
    return 0;
  }

후↓

  @RequestMapping("/contact/update")
  public Object update(String name, String email, String tel, String company) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        contacts[i] = createCSV(name, email, tel, company);
        return 1;
      }
    }
    return 0;
  }

2단계 - 이메일로 연락처를 찾아 배열 인덱스를 알아내는 코드를 분리한다.

ContactController.indexOf()

  // 기능:
  // - 이메일로 연락처 정보를 찾는다.
  // - 찾은 연락처의 배열 인덱스를 리턴한다.
  //
  int indexOf(String email) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        return i;
      }
    }
    return -1;
  }

전↓

  @RequestMapping("/contact/get")
  public Object get(String email) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        return contacts[i];
      }
    }
    return "";
  }

후↓

  @RequestMapping("/contact/get")
  public Object get(String email) {
    int index = indexOf(email);
    if (index == -1) {
      return "";
    } 

    return contacts[index];

  }

전↓

  @RequestMapping("/contact/update")
  public Object update(String name, String email, String tel, String company) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) { 
        contacts[i] = createCSV(name, email, tel, company);
        return 1;
      }
    }
    return 0;
  }

후↓

  @RequestMapping("/contact/update")
  public Object update(String name, String email, String tel, String company) {
    int index = indexOf(email);
    if (index == -1) {
      return 0;
    }

    contacts[index] = createCSV(name, email, tel, company);
    return 1;
  }

java documentation 11 api

https://www.oracle.com/java/technologies/java-se-support-roadmap.html

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html

리팩토링
주석이 붙은 코드는 그대로 분리시킨다.
메소드 이름은 적절하게 짓는다.

3단계 - 배열 항목 삭제 코드를 분리한다.

코드의 기능을 명확하게 설명하고 싶을 때도 메소드를 활용하여 코드를 분리한다.

이미 자바에 존재하는 메소드를 흉내내는 거 자체가 나중에 이해하고 쓰는

지금 당장은 안 쓰지만 만들어 놓자

  // 기능:
  // - 배열에서 지정한 항목을 삭제한다.
  // 
  String remove(int index) {
    String old = contacts[index];
    for (int i = index + 1; i < size; i++) {
      contacts[i-1] = contacts[i]; // 한 칸씩 앞으로 당긴다
    }
    size--;
    return old;
  }

전 ↓

  @RequestMapping("/contact/delete")
  public Object delete(String email) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        // 현재 위치의 다음 항목에서 배열끝까지 반복하여 앞으로 값을 당겨온다.

        for (int j = i + 1; j < size; j++) {
          contacts[j-1] = contacts[j];
        }
        size--;
        return 1; 
      }
    }
    return 0;
  }

전 ↓

  @RequestMapping("/contact/delete")
  public Object delete(String email) {
    int index = indexOf(email);
    if (index == -1) {
      return 0;
    }

    for (int j = index + 1; j < size; j++) {
      contacts[j-1] = contacts[j];
    }
    
    return 1;

  }

후 ↓

  @RequestMapping("/contact/delete")
  public Object delete(String email) {
    int index = indexOf(email);
    if (index == -1) {
      return 0;
    }

    remove(index);
    return 1;

  }

4단계 - 배열 크기를 자동으로 늘린다.

0개의 댓글