리턴 값이 없는 함수를 console.log로 출력하면?
undefined 나옴
51-자바스크립트 / 13 페이지
파라미터 : 함수가 작업하는 데 사용할 값을 받는 변수
자바스크립트 함수를 호출할 때 아규먼트의 개수는 함수에 정의된 파라미터 개수와 일치하지 않아도 된다. 에러 안 뜸.
parameter : 값을 받는 변수
argument : 함수를 호출할 때 넘겨주는 값
같은 이름의 함수가 동시에 존재할 수 없다. 맨 마지막에 정의된 함수로 됨.
기존 함수를 덮어쓴다.
자바스크립트의 모든 함수에 arguments라는 내장 변수가 존재한다.
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 라는 함수의 주소를 넘기는 거
함수를 넘긴다 → 함수의 주소를 넘긴다
호출 당한 게 아니라 다이렉트로 우리가 호출한 거
파라미터나 변수로 넘겨주는 게 콜백
파라미터로 받은 함수를 호출하는 것이 아니기 때문에 콜백 함수가 아니다.
함수 안에서 함수를 만들어 리턴할 수 있다.
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번까지
• 특정 기능을 수행하는 코드에 대해 메서드로 정의해두면 재사용이 쉽고 코드 유지보수가 쉽다.
• 코드를 메서드로 분리하는 경우
‐ 유사한 코드가 여러 곳에서 중복 사용될 때
‐ 코드의 기능을 명확하게 설명하고 싶을 때
중복 코드를 분리하여 메소드로 정의한다.
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;
}
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
리팩토링
주석이 붙은 코드는 그대로 분리시킨다.
메소드 이름은 적절하게 짓는다.
코드의 기능을 명확하게 설명하고 싶을 때도 메소드를 활용하여 코드를 분리한다.
이미 자바에 존재하는 메소드를 흉내내는 거 자체가 나중에 이해하고 쓰는
지금 당장은 안 쓰지만 만들어 놓자
// 기능:
// - 배열에서 지정한 항목을 삭제한다.
//
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;
}