JavaScript
- ECMA 스크립트 (ES)
- 객체 기반의 스크립트 프로그래밍 언어 (지향보다는 기반)
- 웹 프로그래밍 언어
- 처음엔 server 가 아닌 client 쪽에서 처리하고 싶어서 언어가 만들어졌는데,
가볍고 용량이 적다 보니 server 쪽에서도 사용 가능해져서 server 쪽도 사용하게 됨 - 동적
- 함수 기반의 언어
- html 을 하나의 객체로 보고, 참조변수를 통해 접근 ==>html 을 document(참조 변수) 를 통해 접근
- 구문이 맞지 않아도 에러가 뜨지 않아서 어디 부분이 에러인지 구분 하기 어려움
JavaScript 특징
- html 에 head / body 에 넣을 수 있는데 보통 body 내에 들어감
- 컴파일 없이 한줄 한줄 해석하며 바로 명령어를 실행하는 인터프리터 언어 HTML의 특정 요소를 선택하여 다양한 이벤트 ( 마우스 클릭, 키보드 입력 등 )에 따라 어떤 동작을 하도록 기능을 넣을 수 있음
JavaScript 사용 방법
내부 스크립트
# p240517/ex01.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>[JavaScript] 방식 1. 내부 스크립트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script>
document.write("내부 스크립트입니다.");
</script>
<h1>JavaScript File</h1>
</body>
</html>
외부 스크립트
# p240517/js/test.js
document.write("외부 파일입니다.");
# p240517/ex02.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>[JavaScript] 방식 2. 외부 스크립트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 방법 1. -->
<!-- head 에 넣어주었지만, 실행 결과는 body 에 보여짐 -->
<!-- <script src="js/test.js"></script> -->
</head>
<body>
<!-- 방법 2. -->
<script src="js/test.js"></script>
<h1>JavaScript File</h1>
<!-- 방법 3. -->
<script src="js/test.js"></script>
</body>
</html>
JavaScript Error !
- 인터프리터 언어라 특정 라인에 에러가 생기면 멈춘다

JavaScript 변수(Variable) 선언 방법
- var -> 선언 위치에 따라 다르지만 보통 전역 변수, 기본값이라 생략 가능, var 변수에 함수를 저장하고 다시 값을 저장하면 변경될 위험이 있어 사용하지 않음
- let -> 블랙 라벨, 전역에 선언된 let 은 global 영역이 아닌 script 영역으로 들어감
- const -> java의 final 와 결이 비슷
- 하나의 코드를 작성할 때 (;) 를 넣는데, 생략해도 에러 발생 x
- 초기화하지 않았으면 undefined 값이 보여짐
- undefined 는 초기화를 하지 않았다는 뜻, null 과 전혀 다름
# p240522/hoisting.html
[var, let, const]
- var 는 함수 레벨 스코프, let 과 const 는 블랙 레벨 스코프
- var 는 선언된 변수를 선언 전에 접근 가능
- let 과 const 는 불가능 (error)
- var 는 이미 선언된 이름과 같은 이름의 변수를 여러 개 선언 가능 (덮어 씌워짐)
- let 과 const 는 불가능 (error)
- var 와 let 은 변수 선언과 동시에 초기화를 하지 않아도 되지만,
const 는 반드시 초기값을 설정해야 함
- var 와 let 은 값 변경이 가능하지만,
const 는 값 변경 불가능
var 는 기본적으로 global 영역에 들어오는데 function 에서 정의하면 지역변수가 됨
var a; // 한개씩 선언
let b;
var a, i; // 동시에 선언
var sum = 0; // 선언과 초기화
let i=0, sum=10, message="Hello"; // 동시에 선언과 초기화
var num;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
num = 100;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
num = 5n;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br>");
# <실행 결과>
num >> undefined
num type >>undefined
num >> 100
num type >>number
num >> 5
num type >> bigint
변수의 데이터 타입
# p240517/type01.html
[ 기본 타입 ] 자료형 Primitive Type
- number : 숫자(정수, 실수)
모든 숫자를 실수로 처리
화면에 소수점이 표현 되지 않아 그렇게 보이지 않음
- bigint : 정수 [ -(2의 53승-1) ~ (2의 53승-1) ]
- string : 문자열
"" or '' 사용 가능
- underfined : 초기화되지 않은 상태, 변수 초기화에 사용
- null : 객체 변수 초기화 사용
- NaN : Not a Number
1 . 변수에 아무런 값을 넣지 않았을 때
<script>
var num;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> undefined
num type >>undefined
2. 변수에 숫자(정수/실수) 넣었을 때
<script>
num = 100;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 100 // 100.0 으로 나오지만 화면엔 그렇게 안나옴
num type >>number
3. 변수에 정수값 넣었을 때
<script>
num = 5n;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 5
num type >>bigint
4. 변수에 문자열 넣었을 때
<script>
num = '하이';
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 하이
num type >>string
5. 변수에 boolean 넣었을 때
<script>
num = true;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> true
num type >>boolean
문자열 리터럴
# p240517/type02.html
[문자열]
* 템플릿 리터럴 : 백틱 사용
: 이중 따옴표나 작은 작은표 대신 백틱(`)을 사용해서 표현
: 작은 따옴표와 혼동할 수 있으나, 백틱은 일반적으로 키보드 tab 키 위에 있음
: 플래이스 홀더를 이용한 &{expression} 으로 표현식 사용ㅇ

문자열 관련 함수
# p240517/type03.html
문자열 길이 : length()
<script>
// string 의 참조변수 today
// string = 객체
const today = 'Good~';
// 문자열 길이
console.log('문자열 길이 >> ' + today.length); # 문자열 길이 >> 5
</script>
특정 문자 변경 : replace(변경할 문자, 대체할 문자)
1) 일치하는 첫 번째만 변경
2) 일치하는 모두 변경
<script>
const today = 'Good~';
// - 일치하는 첫 번째만 변경
console.log(today.replace('o', 'ap-'));
// - 일치하는 모두 변경
console.log(today.replaceAll('o', 'ap-'));
</script>
# 실행 결과
Gap-od~
type03.html:27 Gap-ap-d~
특정 위치의 문자 추출
1) 문자열 .substring(시작 인덱스, 끝 인덱스)
<script>
const today = 'Good~';
// 1. 문자열.substring (시작 인덱스, 끝 인덱스)
console.log(today.substring(1, 4));
console.log('음수 인덱스 : ' + today.substring(1, -1)); // 처리 못함(지원안됨)
</script>
# 실행 결과
ood
음수 인덱스 : G
2) 문자열 .slice(시작 인덱스, 끝 인덱스)
<script>
const today = 'Good~';
// 2. 문자열.slice(시작 인덱스, 끝 인덱스)
console.log(today.slice(1, 5));
console.log(today.slice(1, -1));
console.log(today.slice(1)); // 시작 인덱스부터 끝까지
console.log(today.slice(-4));
console.log('-4 ~ 0 : ' + today.slice(-4, 0)); // 잘못됨
</script>
# 실행 결과
ood~
ood
ood~
ood~
-4 ~ 0 :
특정 문자 기준으로 분리(쪼개기) : split(특정 문자)
- 배열로 리턴
- 기준으로 사용된 문자는 요소에 없음
<script>
const today = 'Good~';
console.log(today.split('d'));
</script>
# 실행 결과
(2) ['Goo', '~']
특정 문자 추가 : 문자열.padStart(문자열 전체 길이, 추가할 문자)
<script>
const today = 'Good~';
// 문자열.padStart(문자열 전체 길이, '추가할 문자')
console.log(today.padStart(10, '*'));
console.log(today.padEnd(10, '*'));
</script>
# 실행 결과
*****Good~
Good~*****
특정 문자 찾기 : include(찾고자 하는 문자열) => true / false 리턴
<script>
const today = 'Good~';
console.log('d : ' + today.includes('d'));
console.log('G : ' + today.includes('G'));
console.log('Go : ' + today.includes('Go'));
console.log('go : ' + today.includes('go'));
</script>
# 실행 결과
d : true
G : true
Go : true
go : false
특정 문자의 위치(index) 리턴 : indexof(찾고자하는 문자열)
- 있음 : 탐색된 첫 번째 문자의 인덱스 리턴
- 없음 : -1 리턴
<script>
const today = 'Good~';
console.log(today.indexOf('o'));
console.log(today.indexOf('Go'));
console.log(today.indexOf('d'));
console.log(today.indexOf('H'));
</script>
# 실행 결과
1
0
3
-1
문자 반복 : repaeat(반복할 횟수)
<script>
const today = 'Good~';
console.log(today.repeat(3));
console.log('홍길동'.repeat(3));
</script>
# 실행 결과
Good~Good~Good~
홍길동홍길동홍길동
대/소문자 변경
<script>
const today = 'Good~';
console.log(today.toUpperCase());
console.log(today.toLowerCase());
</script>
# 실행 결과
GOOD~
good~
공백 제거
<script>
const say = ' hi ~ ! ';
console.log(say);
console.log('|' + say + '|');
console.log('|' + say.trimStart() + '|'); // 왼쪽 공백 제거
console.log('|' + say.trimEnd() + '|'); // 오른쪽 공백 제거
console.log('|' + say.trim() + '|'); // 양쪽 공백 제거
</script>
# 실행 결과
hi ~ !
| hi ~ ! |
|hi ~ ! |
| hi ~ !|
|hi ~ !|
참조 타입 - 배열
# p240517/type04.html
<script>
// [배열]
var arr = [2, 4, 2.5, 'ㅎㅇ'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[3]);
console.log('arr 타입 : ', typeof arr); // object , 배열로 출력되지만 타입은 object 로 보여짐
console.log('arr[0] 타입 : ', typeof arr[0]);
</script>
# 실행 결과
Array(4)
2
4
ㅎㅇ
arr 타입 object
arr[0] 타입 number
<script>
// 배열의 요소에 배열로 와도 상관 x
var arr2 = [arr, 3, '즐거운 하루'];
console.log(arr2);
console.log('arr2[0] : ' + arr2[0]);
console.log('arr2[0] : ' + arr2[0][2]);
console.log('하루 추출 : ' + arr2[2].slice(-2));
</script>
# 실행 결과
Array(3)
arr2[0] : 2,4,2.5,ㅎㅇ
arr2[0] : 2.5
하루 추출 : 하루
참조 타입 - 객체
# p240517/type04.html
<script>
// [객체]
// [property(요소)] {key: value};
// 순서 보장 x ==> index 개념 없고, key 값으로 찾기
var obj = {
name : '홍길동',
age : 35,
};
console.log(obj);
console.log('obj 타입 : ' + typeof obj);
// [property(요소) 접근] 방법 1
// : 점 접근
// : key 그대로 사용
console.log('name 값 출력 : ', obj.name);
// [property(요소) 접근] 방법 2
// : [] 접근
// : key를 문자열 취급하여 사용
console.log('name 값 출력 : ', obj['name']);
</script>
# 실행 결과
Object
obj 타입 : object
name 값 출력 : 홍길동
name 값 출력 : 홍길동
배열 관련 함수(type05,06)
# p240517/type05.html
<script>
// 배열을 내부적으로 객체 형태로 관리
// index 또는 key 로 봄
// const 인데 추가/삭제가 되는 이유는 ?!
// : 주소가 오기 때문에 크게 문제가 없음
const even = [2, 4, 6];
console.log(even);
console.log('even[0] : ' + even[0]);
console.log('even[2] : ' + even[2]);
// [property(요소) 추가]
// 1) 맨 뒤에 추가
even.push(8);
console.log('1) 요소 1개 맨 뒤 추가 : ' + even);
even.push(10, 12);
console.log('1) 요소 2개 맨 뒤 추가 : ' + even);
// 2) 맨 앞에 추가
even.unshift(-2);
console.log('2) 요소 1개 맨 앞 추가 : ' + even);
even.unshift(-4, -6);
console.log('2) 요소 2개 맨 앞 추가 : ' + even);
// [property(요소) 삭제]
// 1) 맨 뒤에서 삭제
console.log('현재 even : ' + even);
const pop1 = even.pop();
const pop2 = even.pop();
console.log('pop1 : ' + pop1);
console.log('pop2 : ' + pop2);
// 2) 맨 앞에서 삭제
console.log('현재 even : ' + even);
const shift1 = even.shift();
const shift2 = even.shift();
console.log('shift1 : ' + shift1);
console.log('shift2 : ' + shift2);
</script>
# 실행 결과
Array(5)
even[0] : 2
even[2] : 6
1) 요소 1개 맨 뒤 추가 : 2,4,6,8
1) 요소 2개 맨 뒤 추가 : 2,4,6,8,10,12
2) 요소 1개 맨 앞 추가 : -2,2,4,6,8,10,12
2) 요소 2개 맨 앞 추가 : -4,-6,-2,2,4,6,8,10,12
현재 even : -4,-6,-2,2,4,6,8,10,12
pop1 : 12
pop2 : 10
현재 even : -4,-6,-2,2,4,6,8
shift1 : -4
shift2 : -6
p240517/type06.html
<script>
const odd = [1, 3, 5];
console.log('odd >> ' + odd);
console.log('\n');
// [문법] 배열.slic(시작 인덱스, 끝 인덱스)
// : 시작 인덱스에서 끝 인덱스 포함 전까지 자른 배열 리턴
copy_odd = odd.slice(0, 2);
console.log('copy_odd >> ' + copy_odd);
console.log('odd >> ' + odd);
console.log('\n');
// -2 인덱스에서 끝까지
copy_odd_two = odd.slice(-2);
console.log('copy_odd_two >> ' + copy_odd_two);
console.log('odd >> ' + odd);
console.log('\n');
// 추가, 삭제
// splice(스플라이스)
// [문법] 배열.splice(시작 인덱스, 개수, 추가요소1, 추가요소2)
// : 3번째 요소(추가요소1)부터 추가
// [문법] 배열.splice(start, deleteCount) : 시작 인덱스에서 개수만큼 요소 삭제
// 추가
odd.splice(-1, 0, '칠');
console.log('추가한 odd >> ' + odd);
console.log('\n');
// 삭제
odd.splice(1, 1);
console.log('삭제한 odd >> ' + odd);
console.log('\n');
// 추가
odd.splice(0, 1, '하나');
console.log('추가한 odd >> ' + odd);
odd.splice(0, 2, '하나', '둘', '셋');
console.log('추가한 odd >> ' + odd);
console.log('\n');
// [배열 요소 추가]
// [문법] 배열.concat(추가할 요소, 추가할 배열, ...)
console.log('현재 odd >> ' + odd);
concat_odd = odd.concat(7, 9); // 복사본을 변수에 저장
console.log('concat_odd >> ' + concat_odd);
console.log('odd >> ' + odd);
console.log('\n');
// 인수로 배열을 추가했지만, 배열의 요소가 추가됨
concat_odd2 = odd.concat([11, 12]);
console.log('concat_odd2 >> ' + concat_odd2);
console.log('odd >> ' + odd);
console.log('\n');
/* [특정 요소 찾기(탐색)]
[문법]
1) 배열.indexOf(item, from); : 인덱스 from 부터 시작해서 item 탐색
: 있으면 index 리턴, 없으면 -1 리턴
2) 배열.lastIndexOf(item, from) : 마지막 인덱스부터 item 탐색
: 있으면 index 리턴, 없으면 -1 리턴
3) 배열.includes(item, from) : 인덱스 from 부터 시작해서 item 탐색
: 있으면 true 리턴, 없으면 false 리턴
*/
arr = [1, 10, false, NaN, null, 10];
console.log('[있는 값] 10 찾아라 !');
console.log('indexOf : ' + arr.indexOf(10));
console.log('lastIndexOf : ' + arr.lastIndexOf(10));
console.log('includes : ' + arr.includes(10));
console.log('\n');
console.log('[없는 값] 2 찾아라 !');
console.log('indexOf : ' + arr.indexOf(2));
console.log('lastIndexOf : ' + arr.lastIndexOf(2));
console.log('includes : ' + arr.includes(2));
console.log('\n');
console.log('[있는 값] false 찾아라 !');
console.log('indexOf : ' + arr.indexOf(false));
console.log('lastIndexOf : ' + arr.lastIndexOf(false));
console.log('includes : ' + arr.includes(false));
console.log('\n');
console.log('[있는 값] null 찾아라 !');
console.log('indexOf : ' + arr.indexOf(null));
console.log('lastIndexOf : ' + arr.lastIndexOf(null));
console.log('includes : ' + arr.includes(null));
console.log('\n');
console.log('[있는 값] NaN(Not a Number) 찾아라 !');
console.log('indexOf : ' + arr.indexOf(NaN));
console.log('lastIndexOf : ' + arr.lastIndexOf(NaN));
console.log('includes : ' + arr.includes(NaN));
console.log('\n');
</script>
# 실행 결과
odd >> 1,3,5
copy_odd >> 1,3
odd >> 1,3,5
copy_odd_two >> 3,5
odd >> 1,3,5
추가한 odd >> 1,3,칠,5
삭제한 odd >> 1,칠,5
추가한 odd >> 하나,칠,5
추가한 odd >> 하나,둘,셋,5
현재 odd >> 하나,둘,셋,5
concat_odd >> 하나,둘,셋,5,7,9
odd >> 하나,둘,셋,5
concat_odd2 >> 하나,둘,셋,5,11,12
odd >> 하나,둘,셋,5
[있는 값] 10 찾아라 !
indexOf : 1
lastIndexOf : 5
includes : true
[없는 값] 2 찾아라 !
indexOf : -1
lastIndexOf : -1
includes : false
[있는 값] false 찾아라 !
indexOf : 2
lastIndexOf : 2
includes : true
[있는 값] null 찾아라 !
indexOf : 4
lastIndexOf : 4
includes : true
[있는 값] NaN(Not a Number) 찾아라 !
indexOf : -1
lastIndexOf : -1
includes : true
객체 축약 표현
1. 키와 값이 같은 경우
# p240517/type07.html
<script>
// 객체 형태
const obj = {
key : '값', // property
};
// 1. 키와 값이 같은 경우
const name = '박보검';
const age = 30;
// 1-1. 키와 값을 모두 설정
// const info = {
// name : name,
// age : age,
// };
// 1-2. 축약 표현
// : 키와 값이 같다면, 값 생략 가능
const info = {name, age};
console.log(info);
console.log('객체 info 의 property name >> ', info.name);
console.log('객체 info 의 property name >> ', info['name']);
</script>
# 실행 결과
Object
객체 info 의 property name >> 박보검
객체 info 의 property name >> 박보검
2. 값이 함수인 경우
# p240517/type07.html
<script>
// 2. 값이 함수인 경우
// 익명 함수, 이름이 있는 거 자체가 의미가 없음
// hello() -> 생략 가능
// 2-1. 원래 형태
// const say = {
// hi : function () {
// console.log('ㅎㅇ 반가룽 ~');
// }
// }
// 2-2. 축햑 형태
const say = {
hi () {
console.log('ㅎㅇ 반가룽 ~')
},
nickname : '홍길동',
}
say.hi(); // hi 가 key
console.log('닉네임 : ', say.nickname);
</script>
객체 함수(type08)
# p240517/type08.html
<script>
const number = {
one : 1,
two : 2,
three : 3,
};
console.log(number);
console.log('key 를 배열로 출력 : ' + Object.keys(number));
console.log('value 를 배열로 출력 : ' + Object.values(number));
console.log('key 와 value 를 하나의 쌍으로 출력 : ' + Object.entries(number));
</script>
# 실행 결과
Object
key 를 배열로 출력 : one,two,three
value 를 배열로 출력 : 1,2,3
key 와 value 를 하나의 쌍으로 출력 : one,1,two,2,three,3
객체 구조 분해 할당 - 1
# p240520/ex01.html
- 배열이나 객체의 속성을 해체하여 개별 변수에 저장
배열
1-1) 변수 개수 = 배열의 요소 개수
// 1-1) 변수 개수 = 배열의 요소 개수
<script>
const even = [2, 4];
const [a, b] = even;
console.log('a >> ' + a); // tyep : 문자열
console.log('b >> ', b); // tyep : 문자열 + object
</script>
# 실행 결과
a >> 2
b >> 4
1-2) 변수 개수 < 배열의 요소 개수
// 1-2) 변수 개수 < 배열의 요소 개수
<script>
console.log("1-2) 변수 개수 < 배열의 요소 개수");
const odd = [1, 3, 5, 7, 9];
const [c, d, ...rest] = odd ;
console.log('c >> ' + c);
console.log('d >> ' + d);
console.log('rest >> ' + rest);
</script>
# 실행 결과
c >> 1
d >> 3
rest >> 5,7,9
1-3) 변수 개수 > 배열의 요소 개수
// 1-3) 변수 개수 > 배열의 요소 개수
<script>
console.log("1-3) 변수 개수 > 배열의 요소 개수");
var [e, f, g] = even;
console.log(e, f, g); // g : undefined
</script>
# 실행 결과
2 4 undefined
초기값 설정
// 초기값 설정
<script>
var [h=10, i=9, j=8] = even;
console.log(h, i, j);
console.log('even >> ' + even);
</script>
# 실행 결과
2 4 8
even >> 2,4
객체
<script>
console.log("2-1) 객체 값 가져오기");
const info = {
nickname : '홍길동',
age : 25,
}
// 변수명 과 키명과 같지 않으면 값이 할당이 안됨
// var { hi, age } = info;
// console.log('hi >>', hi); // hi >> undefined
// 순서 상관 x
var { nickname, age } = info;
var { age, nickname } = info;
console.log('nickname >>', nickname);
console.log('age >>', age);
</script>
# 실행 결과
nickname >> 홍길동
age >> 25
<script>
var { new_nickname, new_age } = info;
console.log('new_nickname >>', new_nickname); // undefined
console.log('new_age >>', new_age); //undefined
var { nickname : new_nickname, age : new_age } = info;
console.log('new_nickname >>', new_nickname);
console.log('new_age >>', new_age);
</script>
# 실행 결과
new_nickname >> undefined
new_age >> undefined
new_nickname >> 홍길동
new_age >> 25
객체 구조 분해 할당 - 2
# p240520/ex02.html
1) 매개변수 : 1개
<script>
const info = { nickname : '홍길동', age : 25 };
// 1) 매개변수 : 1개
function show_info(args) { // 타입 지정 x, 반환형 x
// console.log(args);
console.log("nickname >>", args.nickname);
console.log("age >>", args.age);
}
console.log('\n');
// 함수 호출
show_info(info);
</script>
2) 매개변수 : 2개
<script>
const info = { nickname : '홍길동', age : 25 };
// 2) 매개변수 : 객체의 구조분해
{ nickname, age } = { nickname:nickname, age:age } 값이 생략된 것
function show_info({ nickname, age }) {
console.log("nickname >>", nickname);
console.log("age >>", age);
}
// 함수 호출
show_info(info);
</script>
2-1) 매개변수 : 객체의 구조분해
<script>
const info = { nickname : '홍길동', age : 25 };
// 2-1) 매개변수 : 객체의 구조분해
// -> 변수명을 원하는 변수명으로 지정
function show_info({ nickname:new_nickname , age:new_age }) {
console.log("nickname >>", new_nickname);
console.log("age >>", new_age);
}
// 함수 호출
show_info(info);
</script>
연산자
# p240520/operator-ex01.html
- 산술 연산자 : + - * **(제곱) / %
- 대입 연산자 : =
- 복합대입 연산자 : += -= *= /= %=
- 증감 연산자 : ++ --
- 관계 연산자 : > >= < <=
== != 값만 비교
=== !== 값과 타입 비교
- 논리 연산자 : && || !
- 삼항 연산자 : 조건 ? 참 : 거짓
- 널리쉬(nullish) : 변수 ?? 변수 ?? 변수
여러 개의 피연산자 중 값이 확정된 변수 찾음
null, undefined 제외
- 전개 연산자 : ...배열명
반복 가능한 데이터(배열 요소)를 펼침
산술 연산자
<script>
var n1 = 5;
var n2 = 3;
console.log('제곱 :', n1 ** n2);
console.log('곱하기: ', n1 * n2);
</script>
# 실행결과
제곱 : 125
곱하기: 15
복합대입 연산자
<script>
var n1 = 5;
var n2 = 3;
console.log('n1 **= n2 :', n1);
</script>
# 실행결과
n1 **= n2 : 125
증감 연산자
<script>
var n1 = 5;
var n2 = 3;
n2--;
console.log('후감소 :', n2);
</script>
# 실행결과
후감소 : 2
관계 연산자
<script>
var n3 = 5;
var n4 = '5';
console.log('n3 type :', typeof n3);
console.log('n4 type :', typeof n4);
console.log('n3 == n4 :', n3 == n4);
console.log('n3 === n4 :', n3 === n4);
</script>
# 실행결과
n3 type : number
n4 type : string
n3 == n4 : true
n3 === n4 : false
논리 연산자
<script>
var n3 = 5;
console.log('!true :', !true);
console.log('!n3 :', !n3);
console.log('!-5 :', !-5);
console.log('!0 :', !0);
console.log('!2.5 :', !2.5);
</script>
# 실행결과
!true : false
!n3 : false
!-5 : false
!0 : true
!2.5 : false
삼항 연산자
<script>
var n3 = 5;
var n4 = '5';
var result = (n3 === n4) ? "값이 같다" : "값과 타입이 다르다"
console.log("result :", result)
// (n3 === n4) ? console.log('같다') : console.log('다르다');
</script>
# 실행결과
result : 값과 타입이 다르다
널리쉬(nullish)
// 값이 두개인 경우 앞에 있는 값이 저장되고, 나머지는 순회 x
// 값이 없는 경우 나머지 값을 넣음(null or underfined)
<script>
var n4 = null;
var n5 = null;
var n6 = undefined;
var value = n6 ?? n5 ?? n4;
console.log("value :", value);
</script>
# 실행결과
value : null
전개 연산자, 전개 구문(spread sysntax)
<script>
var even = [2, 4, 6];
console.log('even >>', even);
console.log('even : 전개 연산자 >>', ...even);
var odd = [1, 3, 5];
var number = [even, odd];
// 배열안에 배열이 들어올 때
console.log('number >>', number);
// 배열안에 배열의 요소가 들어오고 싶을 때
var spread_number = [...even, ...odd];
console.log('spread_number >>', spread_number);
</script>
# 실행결과
even >> (3) [2, 4, 6]
even : 전개 연산자 >> 2 4 6
number >> (2) [Array(3), Array(3)]
spread_number >> (6) [2, 4, 6, 1, 3, 5]
대화상자(dialog-box)
1. 경고창 => 사용자에게 경고하기 위해서
2. 확인창 => 사용자에게 2 중의 답을 알기 위해서 (true/false)
3. 입력창 => 사용자에게 입력받기 위해서
1. 경고창
# p240520/dialog-box-alert.html
<script>
// ip:port 내용
// 순서 : h1 > '1번째 출력' > alert > '2번째 출력'
// 특정 라인에서 코드 멈추기 : breakpoint
// 중지점은 태그랑 상관 x
// 단계별 실행 : F8
document.write('1번째 출력<br>');
var answer = alert("경고창입니다."); // undefined
document.write('answer >> ', answer)
document.write('<br>2번째 출력');
</script>


2. 확인창
# p240520/dialog-box-confirm.html
// 사용자가 무엇을 눌렀는지 확인할 수 있음
<script>
var answer = confirm('입력을 완료했나요 ?');
document.write(answer); // true or false
</script>

★ 확인창 퀴즈 !
[문제]
true 와 false 는 변수를 사용해서 쓰기
확인 버튼을 클릭하면,
'리턴값은 true 이고, 확인을 클릭했습니다.' 를 화면에 출력
취소 버튼을 클릭하면,
'리턴값은 false 이고, 취소를 클릭했습니다.' 를 화면에 출력
<script>
var answer = confirm('입력을 완료했나요 ?');
// [방법 1]
var check = (answer) ? "확인" : '취소';
document.write(`리턴값은 ${answer}이고, ${check}을/를 클릭했습니다.`);
// [방법 2]
if (answer) {
document.write(`리턴값은 ${answer}이고, 확인을 클릭했습니다.`);
} else {
document.write(`리턴값은 ${answer}이고, 취소를 클릭했습니다.`);
}
</script>
3. 입력창
# p240520/dialog-box-prompt.html
<script>
// 아무런 입력도 안했을 때 --> 빈문자열
// 취소 버튼 눌렀을 때 --> null
var answer = prompt('오늘 날씨는 ?');
document.write('답변 ... ', answer);
</script>
★ 입력창 퀴즈 !
[문제]
prompt 함수를 이용하여, 정수 1개 입력 받은 후 1 증가된 값 출력
prompt 문구 : 정수 1개 입력하세요. 6
화면 출력 : 1 증가한 값 6 입니다.
<script>
var userNumber = prompt('정수 1개 입력하세요.');
userNumber++;
document.write(`1 증가한 값 ${userNumber} 입니다.`);
</script>


<script>
var userNumber = prompt('정수 1개 입력하세요.');
document.write('userNumber type : ' + typeof userNumber);
document.write('<br>');
userNumber++;
document.write('[자동형변환] userNumber type : ' + typeof userNumber);
document.write('<br>');
// 방법 1
userNumber = parseInt(userNumber) + 1;
document.write('[강제형변환 1번] userNumber type : ' + typeof userNumber);
document.write('<br>');
// 방법 2
userNumber = Number(userNumber) + 1;
document.write('[강제형변환 2번] userNumber type : ' + typeof userNumber);
document.write('<br>');
document.write(`1 증가한 값 ${userNumber} 입니다.`);
</script>
제어문 : 조건문, 반복문
1-1. 조건문 : swith문
# p240520/swith.html
[특이점]
- 자바는 정수만 올 수 있는데, 자바스크립트는 실수도 올 수 있음
<script>
var data = 2.5;
var one = 1;
switch(data) {
case one:
document.write('1이다.');
break
case 2:
document.write('2이다.');
break
case 2.5:
document.write('2.5이다.');
break
default:
document.write('기타');
}
</script>
1-2. 조건문 : if문
# p240520/if.html
[문법]
# 조건 1개
if (조건식) {
명령어;
명령어;
}
# 조건 2개
if (조건식) {
true일 때 명령어;
} else {
false 일 때 명령어;
}
# 조건 3개
if (조건식 1) {
명령어;
} else if (조건식 2) {
명령어;
} else if (조건식 3) {
명령어;
}
<script>
var num = 3;
// num % 2 값이 0 또는 1인데
// if (1) 이 되면 자바스크립트가 자체적으로 논리값으로 변환하여
// true 또는 false 됨 (좋은 형태는 아니지만, 문법상 가능)
if (num % 2 ==1) {
document.write('홀수');
} else {
document.write('짝수');
}
</script>
2-1. 반복문: for문
# p240520/for.html
[문법]
: for문 안에서 변수 선언할 거면 var 보다는 let(지역변수)를 쓰는 것이 좋음
for (let 초기값; 조건식; 증감식)
for (초기값; 조건식; 증감식) {
명령어;
}
<script>
// var num = 1;
for (let num=1; num<11; num++) {
document.write(num);
document.write('<br>');
}
</script>
2-2. 반복문: for in문
# p240520/for-in.html
[문법]
: 초기값, 증감식 x
: property 의 key 를 추출
for (let 변수 in 객체) {
명령어;
}
<script>
var arr = [1, 3, 5, 7, 9];
document.write("arr 배열의 길이 >> ", arr.length); // arr 배열의 길이 >> 5
document.write("<br>");
// 웹 브라우저로 출력
for (let n in arr) {
document.write(n + ' '); // 0 1 2 3 4
}
document.write("<br>");
// console 창으로 출력
console.log("arr >> ", arr); // arr >> (5) [1, 3, 5, 7, 9]
for (let n in arr) {
console.log(n);
}
var obj = { nickname : '홍길동', age : 25 }
// << for-in문 >>
for (let key in obj) {
document.write(key + ' '); // nickname age
}
</script>
2-3. 반복문: for of문
# p240520/for-of.html
[문법]
: property 의 value 를 추출
: Symbol.iterator property 를 가진 반복 가능한 객체에서만 사용 가능
: 배열에서 가능
for (let 변수 of 객체) {
명령어;
}
<script>
var arr = [1, 3, 5, 7, 9];
for (let i of arr) {
document.write(i + ' '); // 1 3 5 7 9
}
document.write('<br>');
var obj = { nickname : '홍길동', age : 25 };
// console.log(obj);
// for (let value of obj) {
// document.write(value + ' ');
// }
</script>
https://jongbeom-dev.tistory.com/139
[JavaScript] iterable, iterator
iterable 객체란 Iterable 객체란 Symbol.iterator라는 Symbol 타입의 값을 속성으로 가지고 그 속성의 값이 인자를 받지 않으며 iterator 객체를 반환하는 메소드인 객체를 의미한다. 배열은 대표적인 iterable
jongbeom-dev.tistory.com
2-4. 반복문: while문
while문 : 기본
# p240520/while-ex01.html
[문법]
초기값;
while (조건식) {
명령어;
증감식;
}
for (let 변수 of 객체) {
명령어;
}
<script>
var num = 1;
while (num < 11) {
document.write(num);
document.write('<br>');
num++;
}
</script>

while문 : 무한루프
# p240520/while-ex02.html
<!-- while 문을 무한 루프로 구현하여, 1 ~ 10 을 출력 -->
<script>
var idx = 1;
while (true) {
document.write(idx);
document.write('<br>');
if (idx == 10) {
break
}
idx++;
}
</script>
2-5. 반복문: do~while문
# p240520/do-while.html
<script>
var num = 1;
do {
document.write(num);
document.write('<br>');
num++;
} while (num < 11)
</script>
함수 : 내장 함수, 사용자 정의 함수
1. 내장 함수 : 이미 정의된 함수
# p240520/function-ex01.html
<script>
// eval : 문자열로 표현된 식을 계산하는 함수
var sum = eval('1 + 2 + 3');
document.write('덧셈 결과 : ', sum);
// 형변환 : 정수
document.write('문자열을 정수로 변환 >> ', parseInt('5'));
document.write('문자열을 정수로 변환 : type >> ', typeof parseInt('5'));
document.write('실수를 정수로 변환 : type >> ', parseInt(5.23));
document.write('실수를 정수로 변환 : type >> ', typeof parseInt(5.23));
// 형변환 : 실수
document.write('문자열을 실수로 변환 >> ', parseFloat('5.25'));
document.write('문자열을 실수로 변환 : type >> ', typeof parseFloat('5.25'));
document.write('정수를 실수로 변환 : type >> ', parseFloat(5));
</script>
# 실행 결과
eval
덧셈 결과 : 6
형변환 : 정수
문자열을 정수로 변환 >> 5
문자열을 정수로 변환 : type >> number
실수를 정수로 변환 : type >> 5
실수를 정수로 변환 : type >> number
형변환 : 실수
문자열을 실수로 변환 >> 5.25
문자열을 실수로 변환 : type >> number
정수를 실수로 변환 : type >> 5
2. 사용자 정의 함수
[특이점]
: 정의된 메소드 매개변수 수가 달라도 호출 가능하며, 에러가 뜨지 않음
: 타입이 지정되어 있지 않기 때문에 들어오는 값이 한정되어있지 않음
아무런 입력을 안했을 때, underfined 타입이 됨
[함수 정의 형태]
1. 매개변수 있고, 리턴값 있음
2. 매개변수 있고, 리턴값 없음
3. 매개변수 없고, 리턴값 있음
4. 매개변수 없고, 리턴값 없음
<< 함수 정의 >>
function 함수명 (매개변수1, 매개변수2) {
명령어;
return 값;
}
<< 함수 호출 >>
함수명(인수1, 인수2);
[return 의미]
- 함수 실행 끝
- 호풀한 쪽으로 리턴값 넘김
[함수 실행 끝]
- return
- body 의 }
[함수 정의 형태]
# p240520/function-ex02.html
<script>
// 2. [함수 호출]
// : 함수를 정의 전에 호출을 했는데도, 호출이 가능
document.write('2. [함수 호출]<br>');
document.write('[함수 정의 전] 호출');
sum(1, 4);
document.write('<br>');
// 1. [함수 정의]
// : 매개변수 있고, 리턴값 있음
document.write('1. [함수 정의]<br>');
function sum (n1, n2) {
document.write('<br>');
document.write('n1 >> ', n1);
document.write('<br>');
document.write('n2 >> ', n2);
document.write('<br>');
document.write('합 >> ', n1 + n2);
document.write('<br>');
}
document.write('[함수 정의 후] 호출');
sum(2, 9);
document.write('<br>');
// 매개변수 수가 달라도 메소드 호출이 가능
sum(1, 3, 5, 7);
sum(6); // NaN
sum(); // NaN
sum('ㅎㅇ', '홍길동');
sum(2.5, 3.1);
sum(2.5, 5);
sum('ㅎㅇ', 2);
sum('ㅎㅇ'); // 문자열 : ㅎㅇundefined, 이어진 것!
</script>
# 실행 결과
2. [함수 호출]
[함수 정의 전] 호출
n1 >> 1
n2 >> 4
합 >> 5
1. [함수 정의]
[함수 정의 후] 호출
n1 >> 2
n2 >> 9
합 >> 11
n1 >> 1
n2 >> 3
합 >> 4
n1 >> 6
n2 >> undefined
합 >> NaN
n1 >> undefined
n2 >> undefined
합 >> NaN
n1 >> ㅎㅇ
n2 >> 홍길동
합 >> ㅎㅇ홍길동
n1 >> 2.5
n2 >> 3.1
합 >> 5.6
n1 >> 2.5
n2 >> 5
합 >> 7.5
n1 >> ㅎㅇ
n2 >> 2
합 >> ㅎㅇ2
n1 >> ㅎㅇ
n2 >> undefined
합 >> ㅎㅇundefined
[함수 정의 형태] 1. 매개변수 없고, 리턴값 없음
# p240521/function-ex01.html
<script>
// 1-1. [함수 정의] 매개변수 없고, 리턴값 없음
function stringPrint() {
console.log('함수 실행 !');
}
// 1-2. 함수 호출
stringPrint();
stringPrint(2); // 인수를 넣어도 정상적으로 실행이 됨
var reslut = stringPrint(); // 여기까지 호출되지만 저장된 값이 없기 때문에
console.log('reslut >> ', reslut) // reslut 는 undefined 가 됨
</script>
# 실행 결과
함수 실행 !
함수 실행 !
함수 실행 !
reslut >> undefined
[함수 정의 형태] 2. 매개변수 없고, 리턴값 있음
# p240521/function-ex02.html
<script>
// 2-1. [함수 정의] 매개변수 없고, 리턴값 있음
function stringReturn() {
console.log('[함수 실행 시작]') // 확인을 위해 작성
return '즐거운 하루';
console.log('[함수 실행 종료]') // 위 코드에서 return 이 되어 있기 때문에 함수 종료, 의미 x
}
// 2-2. 함수 호출
stringReturn(); // console.log 를 찍은 게 아니라 안보여질 뿐, 호출 실행 됐음
var reslut = stringReturn();
console.log('reslut >> ', reslut);
</script>
# 실행 결과
[함수 실행 시작]
[함수 실행 시작]
reslut >> 즐거운 하루
[함수 정의 형태] 3. 매개변수 있고, 리턴값 없음
# p240521/function-ex03.html
<script>
// 3-2. 함수 호출
// 지역변수, 초기화 할 수 있는게 없어서 undefined 가 됨
info();
info('박보검');
info('홍길동', 25);
info('이미자', 32, '운동'); // 매개변수를 더 받아도 error 가 아님
// 3-1. [함수 정의] 매개변수 있고, 리턴값 없음
// << 특징 >>
// - 매개변수와 인수의 자료형이 동일한지 검사하지 않음
// - 매개변수의 개수와 인수의 개수가 같은지 검사하지 않음
// - 매개변수의 개수가 인수의 개수보다 적으면 undefined 저장
function info(name, value) {
console.log('name >> ', name);
console.log('value >> ', value);
console.log('------------------------------------');
}
</script>
# 실행 결과
name >> undefined
value >> undefined
------------------------------------
name >> 박보검
value >> undefined
------------------------------------
name >> 홍길동
value >> 25
------------------------------------
name >> 이미자
value >> 32
------------------------------------
[함수 정의 형태] 4. 매개변수 있고, 리턴값 있음
# p240521/function-ex03.html
<script>
// 4-2. 함수 호출
// 아래 코드를 보고 자바스크립트는 어떠한 형태든 받는다 라는 것을 알 수 있음
// 주소도 받을 수 있음(객체, 함수, 그 외), 뒤에 가서 배울 예정
var reslut = add(); // add(un.., un..) 매개변수가 없어 undefined 계산이 안되기 때문에
console.log('1. 덧셈 결과 >> ', reslut); // 결과값 NaN
var reslut = add(1); // add(1, un..), 같은 변수명을 써도 문제가 안되고, 덮어씌워짐
console.log('2. 덧셈 결과 >> ', reslut); // 결과값 NaN
var reslut = add(1, 3);
console.log('3. 덧셈 결과 >> ', reslut);
var reslut = add(2, 4, 8);
console.log('4. 덧셈 결과 >> ', reslut); // 매개변수를 더 받아도 error 가 아님
var reslut = add('오늘', '하루');
console.log('5. 덧셈 결과 >> ', reslut); // 문자열 작업, type 은 string
var reslut = add(2.4, 1.2);
console.log('6. 덧셈 결과 >> ', reslut);
var reslut = add(5, 1.2);
console.log('7. 덧셈 결과 >> ', reslut);
// 4-1. [함수 정의] 매개변수 있고, 리턴값 있음
// << 특징 >>
// - 매개변수와 인수의 자료형이 동일한지 검사하지 않음
// - 매개변수의 개수와 인수의 개수가 같은지 검사하지 않음
// - 매개변수의 개수가 인수의 개수보다 적으면 undefined 저장
function add(x, y) {
console.log('======================================');
console.log('매개변수 x : ', x);
console.log('매개변수 y : ', y);
var total = x + y;
return total;
}
</script>
# 실행 결과
매개변수 x : undefined
매개변수 y : undefined
1. 덧셈 결과 >> NaN
====================================
매개변수 x : 1
매개변수 y : undefined
2. 덧셈 결과 >> NaN
====================================
매개변수 x : 1
매개변수 y : 3
3. 덧셈 결과 >> 4
====================================
매개변수 x : 2
매개변수 y : 4
4. 덧셈 결과 >> 6
====================================
매개변수 x : 오늘
매개변수 y : 하루
5. 덧셈 결과 >> 오늘하루
====================================
매개변수 x : 2.4
매개변수 y : 1.2
6. 덧셈 결과 >> 3.5999999999999996
====================================
매개변수 x : 5
매개변수 y : 1.2
7. 덧셈 결과 >> 6.2
Arguments 속성
- 함수가 웹 브라우저에 의해 처리가 될 때 위에서 아래로 처리가 되는데 매개변수가 없는
함수에 인수를 넣어줄 때 함수에서 확인 할 수 있음 (글 정리) - 참조변수를 통해 찾아갈 수 있음
# p240521/function-ex5.html
매개변수가 있는 함수를 호출할 때 사용자가 입력한 인수의 정보를 알 수 있음

<script>
// 1. 함수 정의
function avg() {
var total = 0;
console.log('>>> avg() 실행');
console.log('arguments : ', arguments);
console.log('arguments 길이 : ', arguments.length);
for (let i=0; i<arguments.length; i++) {
console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
console.log('총합 : ', total);
}
// 2. 함수 호출
avg(2, 3, 5);
</script>
# 실행 결과
>>> avg() 실행
arguments : Arguments(3) [1, 2, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
arguments 길이 : 3
arguments[0] : 2
arguments[1] : 3
arguments[2] : 5
평균 구하기
- .toFixed(고정할 자리수)
<script>
function avg() {
// 평균 구하기
var total = 0;
for (let i=0; i<arguments.length; i++) {
// console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
var mean = (total / arguments.length).toFixed(2); // .toFixed(고정할 자리수)
return mean;
}
// 2. 함수 호출
var reslut = avg(2, 3, 5);
console.log('avg(2, 3, 5) 호출 결과 : ', reslut);
// console.log('[함수 밖] arguments : ', arguments) error !
</script>
# 실행 결과
avg(2, 3, 5) 호출 결과 : 3.33
★ 왜 error 일까 ?!
console.log('[함수 밖] arguments : ', arguments) error !
- 자바스크립트가 실행이 되면서 gloval 을 사용함
- 한 페이지 스크립트가 여러 개여도 gloval 영역은 하나만 생성
- 사진처럼 공용으로 공유 함
- 자바스크립트가 실행되기 전에 필요한 메모리를 미리 메모리 할당
- 자바스크립트는 property(요소) 로 관리
- script 가 있으면 먼저 스크립트 내에 있는 코드가 위에서 아래로 읽으면서 이름이 있는 것들은 미리 global 영역에 메모리에 올려둠

Parameter 속성
# p240521/function-ex6.html
<script>
function avg() {
// 평균 구하기
var total = 0;
for (let i=0; i<arguments.length; i++) {
// console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
var mean = (total / arguments.length).toFixed(2); // .toFixed(고정할 자리수)
return mean;
}
// 2. 함수 호출
var reslut = avg(2, 3, 5);
console.log('avg(2, 3, 5) 호출 결과 : ', reslut);
// console.log('[함수 밖] arguments : ', arguments) error !
</script>
함수 종류
# 함수 선언식 : 선언적 함수, 함수명 있음
# 함수 리터럴 : 익명 함수, 함수명 없음
# 함수 표현식 : 익명 함수에 변수로 저장, 함수명은 아니고, 이름처럼 사용
# 화살표 함수 : arrow function (나중에 배울것)
함수 선언식
# p240521/function-ex7.html
<script>
// [함수 선언식] 선언적 함수, 일반 함수
// : 함수 정의 전에 호출 가능
// : 함수 호출 시기 제한 없음
// : 함수명 있음
// 2-1. 함수 호출
hi('박보검');
// 1. 함수 정의
function hi(name) {
console.log(name + "님, 안녕하세요 !");
}
// 2-2. 함수 호출
hi('홍길동');
</script>
실행 순서




함수 표현식
# p240521/function-ex7.html
<script>
// [함수 표현식]
// : 익명 함수를 변수에 저장
// : 함수 정의 전에 호출 불가능
// : 함수명 없음(변수를 함수명처럼 씀)
// <내가 정리한 것>
// : function 자체가 변수에 저장이 되는데, 정확히는 주소가 저장된 것
// : 변수를 통해 이름이 생긴 익명 함수
// : 메모리에 저장은 됐지만, 이름이 없어서 두번은 못 씀 하지만 변수에 저장돼서 사용 가능
// 변수(주소) 써서 갔는데 매개변수가 있으니 저장이 됨
// => 이를 통해 함수 선언식과 함수 표현식의 차이점을 알 수 있음
// : 메모리 할당 시기 : 해당 라인이 실행될 때
// : 그럼 미리 올려둬서 좋은 거 아닌가 ? NO, 쓸데없는 메모리까지 차지하게 됨
// 2-1. 함수 호출
// hello('곰돌이'); // error ! hello is not a function
// 1. 함수 정의
var hello = function (name) {
console.log(name + '안녕 ~ !');
}
// 2-2. 함수 호출
hello('이미자'); // 위에 error 가 나면 인터프리터 언어인 자바스크립트라 실행이 안됨
var hey = hello; // hey 를 통해 익명 함수를 찾아갈 수 있음
hey('고양이');
</script>
실행 순서




즉시 실행 함수 : 1회용
# p240521/function-ex7.html
<script>
// [즉시 실행 함수] 1회용 (f(매개변수))(매개변수)
// 초기화 작업, 1번만 쓰고 말 때
// 이러한 코드는 위에 두어야함
(function (name) {
console.log(name + "님, 또 만나서 반가워요 ~ ");
})('멍멍이')
</script>
[함수 선언식과 표현식] 생성과 실행 순서
# p240521/function-ex8.html
<script>
/*
[생성 순서] 함수 선언식 -> 익명 함수
[실행 순서] 익명 함수 -> 함수 선언식
*/
// [함수 선언식] 선언적 함수, 일반 함수
function hi(name) {
console.log(name + ', 안녕 ~ [일반 함수]')
}
// [함수 표현식] 익명 함수를 변수에 저장
// var hi 가 먼저 할당되지만 코드는 위에서 아래로 읽기 때문에 놓침
// 보통 const 로 선언을 많이 함
var hi = function hi(nickname) {
console.log(nickname + ', 님, 안녕하세요 !')
}
// 함수 호출
console.log('>>> 함수 호출 전')
hi('홍길동');
console.log('>>> 함수 호출 후')
</script>
인수
# p240521/function-ex9.html
<script>
// 함수 정의
function hello() {
console.log('Hello ~~~~');
}
function hi() {
console.log('Hi !!!!!');
}
function execute(args) {
console.log('>>> 함수 실행 시작');
args();
console.log('>>> 함수 실행 종료');
}
// 함수 호출
// hello();
execute(hello); // 매개변수에 함수명을 입력, 함수 주소가 해당 함수를 찾아감
execute(hi);
</script>
# 실행 결과
>>> 함수 실행 시작
Hello ~~~~
>>> 함수 실행 종료
>>> 함수 실행 시작
Hi !!!!!
>>> 함수 실행 종료
중첩 함수
# p240521/function-ex10.html
함수 정의 내 함수 정의, 호출 방법 2가지
- 함수 내 함수 호출
- 함수 내에 return 값으로 함수 호출
<script>
// outer function(createHello), inner function(hello)
function createHello() {
console.log('>>> 함수 시작');
function hello(name) { //
console.log('... hello() 함수 시작');
console.log(name + '님, 안녕하세요 !')
console.log('... hello() 함수 종료');
}
// 호출 방법 1. 함수 내 함수 호출
// hello();
console.log('>>> 함수 종료');
// 호출 방법 2. 함수 내에 return 값으로 함수 호출
return hello;
</script>
실행 순서








# p240521/function-ex11.html
<script>
function outer() {
console.log('>>> outer() 실행 시작');
function inner() {
console.log('... inner() 실행 !');
}
inner();
console.log('>>> outer() 실행 종료');
}
console.log('... 프로그램 시작 ...')
outer();
console.log('... 프로그램 종료 ...')
</script>
실행 순서





# p240521/function-ex12.html
<script>
function loopHello() {
let count = 0;
let printHello = function() {
count++; // 5월 22일 수업때 자세히 이야기
console.log(`${count} : Hello`)
if (count == 10) {
clearInterval(s); // 중지
}
}
// 이미 만들어진 function
// 일정한 간격으로 특정한 작업을 실행하고자 할 때 씀, java 의 thread
// 비동기
// 저장된 변수에 인수로 넣어줌
var s = setInterval(printHello, 1000); // 얘가 누군지 모르니까 변수 만들기
}
loopHello();
</script>
# p240521/function-ex12 copy.html
- ex12 코드에서 수정된 파일이 ex12 copy 파일인데 보통 이렇게 많이 쓰임 !
<script>
// 함수 정의
function loopHello() {
let count = 0;
var s = setInterval(function () {
count++; // 5월 22일 수업때 자세히 이야기
console.log(`${count} : Hello`)
if (count == 10) {
clearInterval(s); // 중지
}
} , 1000)
}
// 함수 호출
loopHello();
</script>
화살표 함수
https://print-blue.tistory.com/182
프로그래밍할 때 function 문법을 사용하는 이유
여러가지 기능을 하는 코드를 한 단어로 묶고 싶을 때 (나중에 재사용할 때)입출력 기능을 만들 때
print-blue.tistory.com
- arrow function 을 사용하면 함수 본연의 입출력 기능을 아주 직관적으로 잘 표현이 됨 (쉽고 예쁘게 표현된다는 의미)
화살표 함수 쓰기 전
# p240521/function-ex13.html
<script>
// 화살표 함수 : arrow function (JAVA Lamvba)
// 기본적으로 익명 함수를 변환한 것, 변수 꼭 써야함
var sum = function(a, b) {
return a + b;
}
var result = sum(4, 6);
console.log('result >> ', result);
</script>
화살표 함수 기능 구현
- 함수에 명령어이 하나만 있고, 명령문이 값을 반환하는 경우 {} 와 return 키워드를 제거할 수 있음
- {} 는 명령문이 하나만 있는 경우에만 작동
<script>
// 1) body 의 {} 생략, return 생략
// 매개변수와 바디 사이에 => 화살표 모양 넣기
var sum = (a, b) => a + b;
var result = sum(4, 6);
console.log('result >> ', result);
</script>
<script>
// 2) body 의 {} 명시
// : 리턴하려면, 무조건 return 키워드 명시
// {} 가 들어오는 순간 자동으로 return 이 안됨
// => 썼다는 자체가 익명 함수
var sum = (a, b) => {
return a + b;
}
var result = sum(4, 6);
console.log('result >> ', result);
</script>
화살표 함수의 정의 형태
# p240522/arrow-function-ex02.html
[화살표 함수의 정의 형태]
1. 매개변수 1개, 리턴값 있음
: 매개변수가 1개일 때, () 생략 가능
: 명령어가 1개일 경우, {} 생략 가능
2. 매개변수 없고, 리턴값 있음
: () 생략 불가능
: 명령어가 1개일 경우, {} 생략 가능
3. 매개변수 1개, 리턴값 있음, 명령어 여러 개
: () 생략 가능
: 명령어가 여러 개일 경우, {} 생략 불가능
4. 매개변수 2개, 리턴값 없음, 명령어 여러 개
: () 생략 불가능
: 명령어가 여러 개일 경우, {} 생략 불가능
5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
: () 생략 불가능
: 명령어가 여러 개일 경우, {} 생략 불가능
1. 매개변수 1개, 리턴값 있음
<script>
// 1. 매개변수 1개, 리턴값 있음
var one = args => args + 1;
var result = one(100);
console.log('one(100) 호출 결과 >>', result);
console.log('one() 호출 결과 >>', one()); // NaN
</script>
# 실행 결과
one(100) 호출 결과 >> 101
one() 호출 결과 >> NaN
2. 매개변수 없고, 리턴값 있음
<script>
// 2. 매개변수 없고, 리턴값 있음
// const two = () => {'문자열입니다.'}; // undefined
const two = () => '문자열입니다.';
console.log('two() 호출 결과 >>', two());
console.log('two(100) 호출 결과 >>', two(100));
</script>
# 실행 결과
two() 호출 결과 >> 문자열입니다.
two(100) 호출 결과 >> 문자열입니다
3. 매개변수 1개, 리턴값 있음
<script>
// 3. 매개변수 1개, 리턴값 있음, 명령어 여러 개
const three = args => {
let num = args + 1;
return `1 증가한 값 : ${num}`;
}
console.log('three(5) 호출 결과 >>', three(5));
</script>
# 실행 결과
three(5) 호출 결과 >> 1 증가한 값 : 6
4. 매개변수 2개, 리턴값 없음, 명령어 여러 개
<script>
const four = (a, b) => {
let result = a + b;
console.log(`매개변수 a : ${a}, 매개변수 b : ${b}`);
console.log(result);
}
four(1, 3);
console.log('four(2, 4) 호출 결과 >>', four(2, 4)); // return 값이 없어 undefined
four(); // NaN
</script>
# 실행 결과
매개변수 a : 1, 매개변수 b : 3
4
매개변수 a : 2, 매개변수 b : 4
6
four(2, 4) 호출 결과 >> undefined
매개변수 a : undefined, 매개변수 b : undefined
NaN
5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
<script>
// 5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
// 기본값 : 매개변수가 있을 경우 인수에 저장되고, 없으면 인수에 기본값이 들어옴
// 기본값 설정 : (a=0, b=0) or (a='', b='')
const five = (a=0, b=0) => {
let result = a + b;
console.log('덧셈 결과 : ', result);
}
five('뭉게', '구름');
five(); // 기본값 설정 안했을 때 : NaN
</script>
# 실행 결과
덧셈 결과 : 뭉게구름
덧셈 결과 : 0
호이스팅(hoisting)
# p240522/hoisting-ex01.html
[호이스팅]
: 인터프리터가 변수(와 함수 등)의 메모리 공간을 미리 할당
: 호이스팅 시 변수(외 함수 등)는 undefined 초기화
: 선언과 초기화를 분리 (변수 기준)
# p240522/hoisting.html
[scope]
- global scope (전역 스코프)
: <script> 내 선언된 변수
: 어디서든지 접근 가능
- local scope (지역 스코프)
: {} 내 선언된 변수
: 해당 영역 내에서만 접근 가능
: function level scope - var
: block level scope - let, const
# p240522/hoisting-ex01.html
<script>
// script 자체가 global 영역
// 할당되어야 하는 것들을 미리 할당하는데, 라인 처리가 되지 않아서 초기값을 설정되지 못함
// 그래서 값은 undefined 로 들어옴
// [global scope(글로벌 영역)]
console.log('변수 선언 전 접근');
var a_var;
console.log('a_var 선언 후');
console.log('a_var :', a_var);
var a_hi = '안뇽'; // 변수 선언 후 초기화
console.log('a_hi :', a_hi);
</script>





var 변수와 let 변수 선언
# p240522/hoisting-ex02.html
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
var a_var;
let a_let;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
</script>
실행 순서


그럼 다시
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
</script>
실행 순서


var 변수와 let 변수 선언, const 변수 선언
# p240522/hoisting-ex02.html
값 설정은 라인 처리가 될 때 초기화가 됨
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
// console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
// 상수(const)
// : cf) 리터럴 Literal
// : 선언과 동시에 초기화
const a_const = 20;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
</script>
실행 순서


값 변경
# p240522/hoisting-ex02.html
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
// console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
// 상수(const)
// : cf) 리터럴 Literal
// : 선언과 동시에 초기화
const a_const = 20;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
// 값 변경
var a_var = 100;
// let a_let = 200; // error ! 재선언
a_let = 200; // 영역이 다르기 때문에 가능
// const a_const = 300; // error ! 재선언
a_const = 300;
console.log('[값 변경 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
</script>
실행 순서


scope(스코프)

# p240522/scope-ex01.html
- 보통 함수 선언은 head 태그 내에 선언을 함
<head>
<title>[scope]</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
console.log('=== <head> 내 script ===');
var a_head_var = 100;
let a_head_let = 200;
const a_head_const = 300;
console.log('a_head_var : ', a_head_var);
console.log('a_head_let : ', a_head_let);
console.log('a_head_const : ', a_head_const);
// 함수 선언식
function a_sum(num1, num2) {
console.log('덧셈 결과 : ', num1 + num2);
}
</script>
</head>
<body>
<h1>[scope]</h1>
<script>
console.log('=== <body> 내 script ===')
console.log('a_head_var : ', a_head_var);
console.log('a_head_let : ', a_head_let);
console.log('a_head_const : ', a_head_const);
// 함수 호출
a_sum('뭉게', '구름');
var a_body_var = 5;
console.log('... 종료')
</script>
</body>
실행 순서






만약 body 에서 선언한 a_body_var 를 head 에서 콘솔 로그를 찍으면 될까 ?
안 된 다 !!! 아직 body 에 있는 script 태그를 읽지 않아서 가져 올 수가 없다 !!
# p240522/scope-ex02.html
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one); // 값이 undefined
var a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>
실행 순서






코드 변경 1. 조건문 추가
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one); // 값이 undefined
var a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
// 조건문
if (a_global == 1) {
// [지역변수]
var a_local_two = 100;
console.log('[지역변수] if문 내 a_local_two >> ', a_local_two);
}
console.log('[지역변수] if문 밖 a_local_two >> ', a_local_two);
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>

코드 변경 2. 변수 변경 var -> let
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
// console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one);
// (var)값이 undefined / (let) error 값이 없음
// var a_local_one = 10;
let a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
// 조건문
if (a_global == 1) {
// [지역변수]
let a_local_two = 100;
console.log('[지역변수] if문 내 a_local_two >> ', a_local_two);
}
// console.log('[지역변수] if문 밖 a_local_two >> ', a_local_two);
// (var)값이 undefined / (let) error 값이 없음
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>
실행 순서




var
# p240522/scope-ex03.html
<script>
// 전역변수
var a_one = 1;
let a_two = 2;
const a_three = 3;
for (var a_i=0; a_i<3; a_i++) {
console.log('a_i >> ', a_i);
}
if (a_one == 1) {
var a_four = 4;
console.log('a_four >> ', a_four);
}
function sum() {
var a_five = 5;
console.log('a_five >> ', a_five);
}
console.log('a_one : ', a_one);
console.log('a_two : ', a_two);
console.log('a_three : ', a_three);
</script>

var -> let 변경
# p240522/scope-ex03.html
<script>
// 전역변수
var a_one = 1;
let a_two = 2;
const a_three = 3;
for (let a_i=0; a_i<3; a_i++) {
console.log('a_i >> ', a_i);
}
if (a_one == 1) {
let a_four = 4;
console.log('a_four >> ', a_four);
}
function sum() {
var a_five = 5;
console.log('a_five >> ', a_five);
}
console.log('a_one : ', a_one);
console.log('a_two : ', a_two);
console.log('a_three : ', a_three);
</script>



렉시컬 스코프(lexical scope)
[Lexical Scope]
: Lexical - 어휘의, 사전의;
: 함수를 어디에 정의하였는지에 따라 상위 스코프를 결정하는 것
# p240522/lexical-scope-ex01.html
<script>
var a = 1;
var b = 2;
var c = 3;
function outer() {
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== outer() 호출 전 ===');
outer();
console.log('=== outer() 호출 후 ===');
</script>
# 실행 결과
=== outer() 호출 전 ===
[outer 내] a : 1, b : 20, c : 30
=== outer() 호출 후 ===



function 안에 또 function
# p240522/lexical-scope-ex01.html
<script>
var a = 1;
var b = 2;
var c = 3;
function outer() {
var b = 20;
var c = 30;
function inner() {
var c = 300;
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== inner() 호출 전 ===');
inner();
console.log('=== inner() 호출 후 ===');
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== outer() 호출 전 ===');
outer();
console.log('=== outer() 호출 후 ===');
</script>




# p240522/lexical-scope-ex02.html
<script>
var a_num = 5;
function a_you() {
var a_num = 500;
console.log('== [a_you() 함수 내] a_need() 호출 ==', a_num);
a_need();
}
function a_need() {
console.log('a_need() 함수 내 변수 a_num 접근', a_num)
}
console.log('== a_you() 호출 ==');
a_you();
console.log('== a_need() 호출 ==');
a_need();
console.log('... script 영역 끝 ...');
</script>
실행 순서









[함수] 메모리 할당 시기
#p240522/arrow-function-ex01.html
<script>
console.log('*** script 영역 시작 ***');
// 함수 선언식 : 이름이 있는 함수
function a_one() {
console.log('a_one() 실행');
}
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
console.log('*** script 영역 종료 ***');
</script>


<script>
console.log('*** script 영역 시작 ***');
// 함수 호출 // 추가 !
a_one();
// a_two(); 아직 할당되어 있지 않아서 호출이 안됨
// 함수 선언식 : 이름이 있는 함수
function a_one() {
console.log('a_one() 실행');
}
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
console.log('*** script 영역 종료 ***');
</script>
화살표 함수로 변경하기
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
// 화살표 함수
var a_two = () => console.log('a_two() 실행');



callback 함수
[콜백 함수]
가장 큰 이유 : 비동기 처리 때문
# 매개변수가 함수명 받음
=> 함수 내에서 함수 호출
자바스크립트에서 변수에 함수를 받는 것처럼 생각하면 됨 (JS 에서 흔한 일)
# 함수 내부 처리 결과값을 외부 함수로 내보낼 때
=> return 과 비슷
# 주로 비동기 처리
[문법]
funtion 함수명(callback) { // callback 인수(인자) 라 불림
callback();
}
p240527/callback-ex01.html
일반적인 함수
<script>
// [함수 선언식] 리턴 사용
function add(num1, num2) {
return num1 + num2;
}
// [함수 호출]
var result = add(2, 5);
console.log('result >> ', result);
</script>
callback 함수
제어권이 넘어갔다는 말도 씀
시간 순서대로 처리된 것이 동기 처리
<script>
// [함수 선언식]
console.log('--- add 함수 시작 ---');
function add(num1, num2, callback) { // callback : 매개변수
var result = num1 + num2;
callback(result);
console.log('--- add 함수 종료 ---');
}
function addResult(value) {
console.log('... addResult 함수 시작 ...');
console.log('덧셈 결과 >> ', value);
console.log('... addResult 함수 종료 ...');
}
function addResultTwo(value) {
console.log('___ addResultTwo 함수 시작 ___');
console.log('합 : ', value);
console.log('___ addResultTwo 함수 종료 ___');
}
// [함수 호출]
// add(1, 4); // error ! callback is not a function, 값 설정 undefined 됨
add(1, 4, addResult);
add(2, 5, addResultTwo);
</script>
p240527/callback-ex02.html
함수 내에서 선언된 지역 변수가 보통 return 을 해야 값을 넘길 수 있는데
callback 함수를 통해 return 효과를 나타냄
함수명을 인수로 설정 - 인수로 설정될 함수 미리 정의
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 1) 함수명을 인수로 설정
// 인수로 설정될 함수 미리 정의
// (1-1) 함수 선언식
function addResult(value) {
console.log('a-1. 덧셈 결과 >> ', value);
}
// (1-1) 함수 표현식
const addResult = function(value) {
console.log('a-2. 덧셈 결과 >> ', value);
}
add(1, 3, addResult);
</script>
# 실행 결과
a-1. 덧셈 결과 >> 4
매개변수에 저장된 함수 >>
ƒ addResult(value) {
console.log('a-1. 덧셈 결과 >> ', value);
}
a-2. 덧셈 결과 >> 4
매개변수에 저장된 함수 >>
ƒ (value) {
console.log('a-2. 덧셈 결과 >> ', value);
}

익명 함수를 인수로 설정 (많이 사용)
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 2) 익명 함수를 인수로 설정 (많이 사용)
// [문법] add(매개변수1, 매개변수2, function() {})
add(3, 7, function(value) {
console.log('b. 덧셈 결과 >> ', value);
})
add(1, 3, addResult);
</script>
# 실행 결과
b. 덧셈 결과 >> 10
매개변수에 저장된 함수 >>
ƒ (value) {
console.log('b. 덧셈 결과 >> ', value);
}
화살표 함수를 인수로 설정 (많이 사용)
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 3-1) 화살표 함수를 인수로 설정(많이 사용)
add(7, 9, (value) => {
console.log('c-1. 덧셈 결과 >> ', value)
});
// (형태 3-2) 화살표 함수를 인수로 설정(많이 사용)
add(6, 8, value => console.log('c-2. 덧셈 결과 >> ', value));
</script>
# 실행 결과
c-1. 덧셈 결과 >> 16
매개변수에 저장된 함수 >>
(value) => {
console.log('c-1. 덧셈 결과 >> ', value)
}
c-2. 덧셈 결과 >> 14
매개변수에 저장된 함수 >>
value => console.log('c-2. 덧셈 결과 >> ', value)
p240527/callback-ex03.html
<script>
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('--- add() 실행 종료 ---');
}
add(1, 3, value => {
console.log('덧셈 결과 : ', value);
console.log('== 화살표 함수 실행 종료 ==')
});
console.log('script 영역 끝 !');
</script>
실행 순서





동기/비동기
<네트워크 기준>
[동기] - 시간을 맞추는 것
클라이언트가 서버한테 무언가를 요청할 때,
서버가 응답할 때까지 클라이언트는 작업을 하지 않는다.
[비동기]
클라이언트가 서버한테 무언가를 요청할 때,
서버가 응답할 때까지 클라이언트는 다음 작업을 먼저 한다.
p240527/callback-ex04.html
동기
<script>
// <자바스크립트 기준>
// [동기] - 위에서 아래로 순차적으로 진행
console.log('alert() 실행 전 출력됩니다.');
alert('ㅎㅇ');
console.log('alert() 실행 후 출력됩니다.');
</script>


비동기
<script>
// [비동기]
var count = 1;
console.log('>>> setInterval() 실행 전 >>>');
// setInterval()
// 특정 기능(코드)을 일정한 시간 간격으로 반복 실행
// setInterval(콜백함수, 시간);
setInterval(() => {
console.log('... count : ', count);
count++;
}, 1000);
console.log('>>> setInterval() 실행 후 >>>');
</script>
실행 순서




배열 함수
find
[find]
조건에 맞는 요소(속성) 하나만 찾음
즉, 조건에 맞는 요소(속성)를 찾으면 탐색 중지
find 에서는 for문 기능이 있음, 순회를 돔
찾고자 하는 조건을 넣고, return 을 해줘야 원하는 값을 받을 수 있음
조건에 맞는 요소 1개만 retunrn
조건에 맞는 요소(속성)가 있으면, 해당 요소 리턴
조건에 맞는 요소(속성)가 없으면, undefined 리턴
[문법] 배열.find(function(value[, index[, array]])) [] 생략 가능하다는 뜻
value = 요소 / index = 요소의 인덱스 / array = 배열의 주소
p240527/array-ex01.html
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
// 길이가 2개인 요소 찾기
// 1. 매개변수 value 만 쓸 때, value 는 생략 불가능
const find_result_one = arr.find(value => value.length == 2);
console.log('find_result_one : ', find_result_one);
// 2. 매개변수 다 사용할 때
const find_result_two = arr.find((value, index, array) => {
console.log('value : ', value);
console.log('index : ', index);
console.log('array : ', array);
return value.length == 2; // true 가 되는 순간 return
})
console.log('find_result_two : ', find_result_two);
</script>
# 실행 결과
find_result_one : 하나
value : 하나
index : 0
array : (5) ['하나', '둘', '셋', '넷', '다섯']
array-ex01.html:39 find_result_two : 하나
filter
[filter]
조건에 맞는 여러 요소 모두 찾음
조건에 맞는 여러 요소를 모두 찾아 배열로 리턴
[문법] 배열.filter(function(value[, index[, array]])) [] 생략 가능하다는 뜻
p240527/array-ex02.html
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const filter_result = arr.filter(value => value.length == 3); // 빈문자열 리턴
console.log('filter_result >> ', filter_result);
const filter_result = arr.filter(value => value.length == 2);
console.log('filter_result >> ', filter_result);
const filter_result_two = arr.filter((value, index, array) => {
console.log('value : ', value);
console.log('index : ', index);
console.log('array : ', array);
return value.length == 2;
});
console.log('filter_result_two >> ', filter_result_two);
</script>

map, forEach
p240527/array-ex03.html
map
[map]
배열 요소를 순회하면서, 특정 작업(기능) 수행(실행)
배열 리턴
복사본을 리턴, 원래 데이터는 영향 x
실제 원하는 기능은 인수로 넣어주는 형태, 외부에서 넣어주는 게 콜백 함수
[문법] 배열.map(function(value[, index[, array]]))
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const map_result = arr.map(value => value + '! 좋아요!');
// 확인할 때 데이터 타입을 구분하기 위해서 문자열과 데이터를 따로 출력함
console.log('map_result >> ');
console.log(map_result);
console.log('arr >> ');
console.log(arr); // 원본은 그대로 있는 걸 확인하면서 알 수 있는 점은 map 은 복사본
</script>
# 실행 결과
map_result >>
(5) ['하나! 좋아요!', '둘! 좋아요!', '셋! 좋아요!', '넷! 좋아요!', '다섯! 좋아요!']
arr >>
(5) ['하나', '둘', '셋', '넷', '다섯']
forEach
// [forEach]
배열 요소를 순회하면서, 특정 작업(기능) 수행(실행)
리턴 없음 (undefined)
[문법] 배열.forEach(function(value[, index[, array]]))
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const forEach_result = arr.forEach(value => console.log(value + '! 좋아요!'));
console.log('forEach_result >> ');
console.log('arr >> ');
console.log(arr); // 원본은 그대로 있는 걸 확인하면서 알 수 있는 점은 forEach 은 복사본
</script>
# 실행 결과
하나! 좋아요!
둘! 좋아요!
셋! 좋아요!
넷! 좋아요!
다섯! 좋아요!
forEach_result >>
arr >>
(5) ['하나', '둘', '셋', '넷', '다섯']
배열 함수 예제
p240527/array-ex04.html
배열 even 의 요소를 1 증가 후, (복사본) 출력
<script>
const even = [2, 4, 6, 8, 10];
// [forEach]
// 1) 익명 함수
even.forEach(function (args) {
console.log(args + 1);
});
// 2) 화살표 함수
even.forEach(args => console.log(args + 1));
console.log('\n');
// [map]
console.log('map_result >> ');
console.log(even.map(args => args + 1));
</script>
# 실행 결과
[forEach]
1) 익명 함수
3
5
7
9
2) 화살표 함수
3
5
7
9
[map]
map_result >>
(5) [3, 5, 7, 9, 11]
배열 even 의 요소를 1 증가
<script>
// 배열 even 의 요소를 변경
even.forEach((value, index, array) => {
array[index] = value + 1;
});
console.log('even >>');
console.log(even);
</script>
# 실행 결과
even >>
(5) [3, 5, 7, 9, 11]
일반 for 문과 forEach() 함수 비교
p240527/array-ex05.html
<script>
// 배열
const student = ['홍길동', '박보검', '이미자'];
// 함수 표현식
const info = function(value, index) {
console.log(`value : ${value}, index : ${index}`);
};
</script>
일반 for문
<script>
console.log('<< for문 >>');
for(let index=0; index<student.length; index++) {
info(student[index], index); // info() 함수 호출
}
</script>
# 실행 결과
forEach()함수
<script>
console.log('<< forEach() >>');
// student.forEach(info); // info() 함수 호출
const forEach_result = student.forEach(info);
console.log(forEach_result);
// undefined
// : return 이 없으면 undefined 로 저장
</script>
# 실행 결과
map() 함수
<script>
// cf) map() 함수
console.log('<< map() >>');
// student.map(info); // info() 함수 호출
const map_result = student.map(info);
console.log(map_result);
// (3) [undefined, undefined, undefined]
// : callback 함수 사용할 때 return 사용
// : info() 에서 return 을 해주지 않아서
// 만약 배열 형태로 값을 하고 싶을 때 info()의 <// 추가> 부분 확인
</script>
# 실행 결과

closure (클로저)
[클로저] closure
# 함수 내부에서 만든 지역변수가 사라지지 않고 계속 유지하는 상태
# 클로저 : 함수와 그 함수가 정의 되었을 때의 렉시컬 환경의 조합
# 클로저는 자신이 생성될 때 환경(Lexical environment)을 기억하는 함수
p240527/closure-ex01.html
<script>
function outer() {
var count = 1;
function inner() {
count++;
console.log('count >> ', count);
}
return inner;
}
var result = outer();
result();
</script>
실행 순서






<script>
function outer() {
var count = 1;
function inner() {
count++;
console.log('count >> ', count);
}
console.log('[outer 지역변수 count] >> ', count);
return inner;
}
// inner() 에서 사용한 count(복사본)
// inner 주소를 갖고 실행, inner 의 local 이 된 것 (outer() 아님)
// inner 에 저장된 count 가 저장되어 있는 값을 가지고 옴
var result = outer();
result();
result();
result();
// outer() 에서 사용한 count(원본)
// outer 가 실행되면, count 가 지역 변수라 당연히 1이 나옴
outer();
result();
console.log('... script 영역 종료 ...')
</script>
# 실행 결과
[outer 지역변수 count] >> 1
count >> 2
count >> 3
count >> 4
[outer 지역변수 count] >> 1
count >> 5
... script 영역 종료 ...
실행 순서






p240527/closure-ex02.html
<script>
// 클로저 형태 o ================================================
// [함수 선언식]
function creatCount() {
console.log('=== creatCount() 함수 시작 ===');
var count = 0; // 상위 스코프의 지역변수, 별도로 따로 관리되는 형태
console.log('지역변수 count >> ', count);
console.log('=== creatCount() 함수 종료 ===');
// 클로저가 사용하는 자유 변수
// inner() 에서 쓰는 상위 스코프의 지역변수만 ! 기억하고 다른 건 기억x
// 근데 이 코드에서는 계속 호출이 되는데 기억을 하고 있어야 해서 이러한 개념을 클로저
// 폐쇄적임, 닫혀있음
// 해당 지역변수는 다른 곳에서 사용 x
// var count = 0;
// 함수 내에 지역변수를 선언안하는 이유
// : 매번 실행될 때마다 count = 0 이 먼저 실행되기 때문에 값이 초기화됨
// return function () {
// count++;
// return count;
// }
return () => ++count;
// 후증가를 하면 결과값이 다름
// 함수 내에 addCount() 호출하지 않아 이름이 의미가 없음
// return addCount;
}
// 문제가 생기는 점 : 함수가 따로 실행될 때
var returnAddCount = creatCount();
for(let i=0; i<3; i++) {
console.log(i+1, "회 : returnAddCount() 호출 >> ", returnAddCount());
}
// returnAddCount();
// returnAddCount();
// returnAddCount();
console.log('... script 영역 종료 ...')
</script>
# 실행 결과
=== creatCount() 함수 시작 ===
지역변수 count >> 0
=== creatCount() 함수 종료 ===
1 '회 : returnAddCount() 호출 >> ' 1 '
2 '회 : returnAddCount() 호출 >> ' 2 '
3 '회 : returnAddCount() 호출 >> ' 3 '
... script 영역 종료 ...
https://jhyonhyon.tistory.com/13
[Javascript] 클로저(Closure)란?
클로저 정의 클로저(Closure)는 자유변수에 접근할 수 있는 내부함수 또는 그 환경을 포함하는 코드를 지칭한다. MDN(Mozilla Developer Network) [모질라 재단및 다른 IT기업들이 사용하는 웹 개발을 위한
jhyonhyon.tistory.com
DOM (document)
특정 엘리먼트 찾기 1
1. 단일 element 추출(반환)
- 여러 개인 경우 첫 번째만 추출
1-1) document.getElementById('아이디')
1-2) document.querySelector('선택자')
아이디 : #아이디
클래스 : .클래스
태그 : 태그
2. 복수 element 추출(반환)
2-1) document.getElementsByClassName('클래스명')
2-2) document.getElementsByTagName('태그')
2-3) document.querySelectorAll('선택자')
document.querySelectorAll('선택자1, 선택자2') -> 선택자1 or 선택자2
p240528/dom-ex01.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 특정 엘리먼트 찾아가기</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>DOM</h1>
<div id="txt" class="c_txt">Hello</div>
<div id="greeting" class="c_txt">안녕</div>
<hr>
<script src="js/dom-ex01.js"></script>
</body>
</html>
p240528/js/dom-ex01.js
// 1. 단일 element 추출(반환)
// JS 프로그래밍 언어
// 복사본을 저장한 게 아니라, 속성을 담아둔 것
// script 태그를 body 닫힌 태그 바로 위에 둠
// 만약 head 태그 쪽에 두면 error 가 발생
// -> 해당 element 에 접근이 안됨
// -> html 렌더링하면서 js 가 먼저 실행되고, 아직 body 태그를 읽지 못햇음
// head 에 오는 script 는 funtion 정의, 전역변수, 초기화 작업 등등이 있음
// Hello 에서 변경된 테스트로 변경된 이유 : 주기적으로 접근
const id_txt = document.getElementById('txt');
const id_greeting = document.querySelector('#greeting');
// 2. 복수 element 추출(반환)
const class_c_txt = document.getElementsByClassName('c_txt');
const div = document.getElementsByTagName('div');
// query 를 쓰면 타입이 HTMLCollection 가 아닌 NodeList 로 됨
const seletorAll = document.querySelectorAll('.c_txt');
const seletorAll2 = document.querySelectorAll('h1, .c_txt'); // 중복이 된다면 중복 제거
// 출력
console.log('id_txt >>', id_txt);
console.log('id_txt type >>', typeof id_txt);
id_txt.innerText = '변경된 텍스트 !';
console.log('id_txt.innerText >>', id_txt.innerText);
console.log('\n');
console.log('id_greeting >> ', id_greeting);
console.log('id_greeting type >>', typeof id_greeting);
console.log('\n');
console.log('class_c_txt', class_c_txt);
console.log('class_c_txt type >>', typeof class_c_txt);
console.log('class_c_txt[1].innerText >>', class_c_txt[1].innerText);
console.log('class_c_txt[1]["innerText"]) >>', class_c_txt[1]['innerText']);
console.log('class_c_txt.greeting.innerText >>', class_c_txt.greeting.innerText);
console.log('class_c_txt.greeting["innerText"] >>', class_c_txt.greeting['innerText']);
console.log('\n');
// HTMLCollection
console.log('div >> ', div);
console.log('div type >>', typeof div);
console.log('\n');
// NodeList
console.log('seletorAll >> ', seletorAll);
console.log('seletorAll type >>', typeof seletorAll);
console.log('seletorAll[1].innerText >> ', seletorAll[1].innerText);
// console.log('seletorAll[1].innerText >> ', seletorAll.greeting.innerText); // id 접근이 안됨
console.log('\n');
console.log('seletorAll2 >> ', seletorAll2);
console.log('seletorAll2 type >>', typeof seletorAll2);
// 아이디라서 쓸 수 있음
// console.log('txt.innerText >>', txt.innerText);
// txt.innerText = '뭐꼬 ㅠㅠ';
특정 엘리먼트 찾기 2
p240528/dom-ex02.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 특정 엘리먼트 찾아가기 2</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
p.paragraph {
text-align: center;
}
</style>
</head>
<body>
<h1 id="title">제목</h1>
<div id="append"></div>
<p class="paragraph">첫번째 단락</p>
<p class="paragraph">두번째 단락</p>
<p class="paragraph">세번째 단락</p>
<hr>
<script src="js/dom-ex02.js"></script>
</body>
</html>
p240528/js/dom-ex02.js
- 자바스크립트를 통해 html 추가한 것은 동적 추가라 불림
- 자바스크립트를 통해 스타일 적용하는 것은 inline 스타일로 들어옴(우선 순위 높음)
// 1. id 를 통해서 title 을 '제목' -> '변경된 제목'
title.innerText = '변경된 제목';
// 2. id 를 통해 append 에 content 로 h3 태그로 '추가된 제목' 넣어주기
// 자바스크립트를 통해 html 추가한 것은 동적 추가 라 불림
append.innerHTML = '<h3>추가된 제목</h3><div>추가 !</div>'
// 3-1. 첫 번째 단락에 접근
const selector = document.querySelector('.paragraph');
// console.log('첫 번째 단락 접근 >> ');
// console.log(selector);
// 3-2. 첫 번째 단락 innerText 변경 후폰트 색상 변경
selector.innerText = '첫 번째 단락만 변경';
selector.style.color = 'blue' // 자바스크립트를 통해 스타일 적용하는 것은 inline 스타일로 들어옴 (우선 순위가 높음)
// 3-3. [문제] 모든 단락의 텍스트를 가로 가운데 정렬하시오.
const paragraph = document.querySelectorAll('p.paragraph');
// [방법 1] for of
// cf) for in : key 추출
// for(let para of paragraph) {
// para.style.textAlign = 'center';
// }
// [방법 2] 함수 정의
// 함수 표현식
// const setTextAlign = function(args) {
// args.style.textAlign = 'center';
// }
// for(let para of paragraph) {
// setTextAlign(para);
// }
// 화살표 함수
// const setTextAlign = args => args.style.textAlign = 'center';
// for(let para of paragraph) {
// setTextAlign(para);
// }
// [방법 3] 배열 함수 forEach
// paragraph.forEach(); // TypeError : ndefined is not a function at NodeList.forEach
const arr_paragraph = Array.from(paragraph); // NodeList -> Array
// console.log('arr_paragraph >> ');
// console.log(arr_paragraph);
console.log('arr_paragraph type >> ', typeof arr_paragraph);
arr_paragraph.forEach(element => element.style.textAlign = 'center');


이벤트
p240528/dom-ex03.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 이벤트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>
<h1 id="greeting">Hello ~~ (。・ω・。)</h1>
<!-- 기본 type값 : submit(이동) -->
<!--
[방법 1] 예전에 많이 사용,
문제점 : 유지보수 쉽지 않음(함수명 바꾸면 다 바꿔야함)
textChange() 은 자바스크립이기 때문에 (;) 생략 가능하지만,
직관성을 위해 붙이는 경우 있음
-->
<button type="button" onclick="textChange();">텍스트 변경</button>
<button type="button" onclick="textBefore();">텍스트 복구</button>
<hr>
<button type="button" id="one">[jQuery] 텍스트 변경</button>
<button type="button" id="two">[jQuery] 텍스트 복구</button>
<script src="js/dom-ex03.js"></script>
</body>
</html>
p240528/js/dom-ex03.js
const element = document.getElementById('greeting');
const greetingInitialText = element.innerText;
// 함수 선언식
function textChange() {
element.innerText = '오늘도 화이팅 ㅋ (。・∀・)ノ゙';
element.style.background = '#ff0';
}
function textBefore() {
element.innerText = greetingInitialText;
element.style.background = 'initial'; // 초기화
}
// [방법 2]
// [jQuery]
// $(선택자); 달러 함수
// const greeting = $('#greeting');
// console.log(greeting);
$('#one').click(() => {
$('#greeting').html('즐거운 오후 ㅋ(~ㅅ~)~zZ');
});
$('#two').click(() => {
$('#greeting').html(greetingInitialText);
});





이벤트 핸들러 등록과 삭제
[이벤트 리스너]
: 이벤트가 발생했을 때, 그 처리를 담당하는 함수
: 이벤트 핸들러(event handler) - 이벤트 감지 후, 실행하는 함수
<문법>
element.addEventListener('이벤트', 이벤트핸들러);
=> 이벤트 핸들러를 이벤트 리스너(addEventListener)에 등록한다 라고 말함
p240528/dom-ex04.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 이벤트 2</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>
<h1 id="greeting">Hello</h1>
<button type="button" class="emoji">이모지 출력 💙💌</button>
<button type="button" class="remove">이모지 해제 💙📧</button>
<script src="js/dom-ex04.js"></script>
</body>
</html>
p240528/js/dom-ex04.js
// [방법 3]
const emoji = document.querySelector('.emoji');
const remove = document.querySelector('.remove');
const h1 = document.querySelector('h1');
// [이벤트 리스너]
// : 이벤트가 발생했을 때, 그 처리를 담당하는 함수
// : 이벤트 핸들러(event handler) - 이벤트 감지 후, 실행하는 함수
// <문법>
// element.addEventListener('이벤트', 이벤트핸들러);
// => 이벤트 핸들러를 이벤트 리스너(addEventListener)에 등록한다 라고 말함
// [이벤트 핸들러]
// [함수 선언식]
function emojiHandler(event) {
console.log(event);
console.log('🎀');
}
// 이벤트 핸들러 해제
// [화살표 함수]
const removeHandler = () => {
console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
emoji.removeEventListener('click', emojiHandler); // 이벤트 핸들러 해제
}
// 이벤트 핸들러를 이벤트 리스너에 등록
// 콜백함수로 넣을 것
// [공부] 화살표 함수로 바꾸기
emoji.addEventListener('click', emojiHandler);
remove.addEventListener('click', removeHandler);
// [공부] 함수 표현식으로 바꾸기
h1.addEventListener('mouseover', () => console.log('마우스 쥐나가요 ~ ㅋ'));
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});
p240528/js/dom-ex04-re.js
// [방법 3]
const emoji = document.querySelector('.emoji');
const remove = document.querySelector('.remove');
const h1 = document.querySelector('h1');
// [함수 표현식으로 정의] ===========================================
// [이벤트 핸들러]
// const emojiHandler = function(event) {
// console.log(event);
// console.log('🎀');
// }
// const removeHandler = function() {
// console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
// emoji.removeEventListener('click', emojiHandler); // 이벤트 핸들러 해제
// }
// const mouseoverChange = function() {
// console.log('마우스 쥐나가요 ~ ㅋ');
// }
// const clickChange = function() {
// h1.innerText = '쪼은 하루 ㅋ';
// h1.style.backgroundColor = 'pink';
// }
// 이벤트 핸들러를 이벤트 리스너에 등록
// emoji.addEventListener('click', emojiHandler);
// remove.addEventListener('click', removeHandler);
// h1.addEventListener('mouseover', mouseoverChange);
// h1.addEventListener('click', clickChange);
// [화살표 함수으로 정의 ] ==========================================
emoji.addEventListener('click', (event) => {
console.log(event);
console.log('🎀');
});
remove.addEventListener('click', (event) => {
console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
// emoji.removeEventListener('click', ); // 이벤트 핸들러 해제
});
h1.addEventListener('mouseover', () => console.log('마우스 쥐나가요 ~ ㅋ'));
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});


module(모듈/기능)
[모듈 가져오기]
- import 키워드 사용
[모듈 내보내기]
- export 키워드 사용
기능이 담긴 자바스크립트 1개 이상의 함수에 한 파일씩 만들어 필요한 html 에 연결
p240530/module/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>모듈</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>모듈</h1>
<script src="index.js"></script>
</body>
</html>
p240530/module/index.js
/*
==========================================
[모듈 가져오기]
- import 키워드 사용
==========================================
*/
console.log('*** index.js 시작 ***');
// 1-1) 방법 1
import { info } from './item.js';
console.log('*** index.js 종료 ***');
p240530/module/item.js
/*
==========================================
[모듈 내보내기]
- export 키워드 사용
==========================================
*/
console.log('*** item.js 시작 ***');
// 1-1) 방법 1
export function info() {
console.log('등록된 상품이 없습니다.');
}
console.log('*** item.js 종료 ***');
처음 보는 error !
웹 브라우저가 html 을 렌더링할 때 호이스팅을 하는데
html 에 index.js 를 읽는데 index.js 에서 다른 파일을 읽어오고 있다고 표시한 것 !

이러한 상황을 알려주기 위해서 html 에 script 에 type 을 지정해줘야한다 !
p240530/module/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>모듈</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>모듈</h1>
<script src="index.js"></script>
</body>
</html>
근데

다른 파일을 추가 했는데 test.js 가 먼저 읽는다
근데 코드는 위에서 아래로 읽는데 test.js 먼저 실행될까 !!!!

그 이유는 import 를 한다는게 다른 파일을 참고 하고 있다는 뜻이고
없는 경우 순수 파일로 실행되고 있다 !
자바스크립트는 순서와 상관없이 순수된 파일 먼저 읽고 참조된 파일은 그 후 실행된다
그래서 코드의 가독성을 돕기 위새 코드 순서도 바꾼다 !
그래서 다시 돌아와 파일 실행 순서를 콘솔창으로 확인해보자
index.js 를 읽으면서 호이스팅이 되는데 import 한 파일도 읽으면서 실행이 되고 index.js 가 실행된다

지금 공부 하는 단계라서 그렇지 원래 import 는 맨 위에 선언 해야된다 !
만약 import 를 하는데 같은 경로 같은 파일인 경우 한 번만 읽는다

내보내기를 할 때 function 과 export 를 분리하게 된다면 여러 개를 한 번에 내보내기 가능하다.

그럼 하나 하나 export 를 해야되나 ? 아래 방법 처럼 하면 된다 !
// 1-3) 방법 3
// as : alias (별명/별칭)
import * as obj from './item.js';
obj.info();
obj.edit();
obj.del();
다시 정리하면 ..!
1. named export
[1. named export]
: 이름이 정의된 내보내기 방식
: 함수, 변수 등 왼쪽에 export 키워드 사용
: 한 모듈 내 여러 개 내보내기 가능
[1. '정의된 내보내기'를 가져오기] ----------------------
<<문법>>
import { 이름 } from '경로/파일명.확장자';
: 이름 변경 불가능
p240530/module/item.js
// 1-1) 방법 1
import { info } from './item.js';
info();
// 1-2) 방법 2
import { edit, del } from './item.js';
edit();
del();
// 1-3) 방법 3
// as : alias (별명/별칭)
import * as obj from './item.js';
obj.info();
obj.edit();
obj.del();
p240530/module/index.js
// 1-1) 방법 1 : exprort 키워드를 함수명 왼쪽에 사용
export function info() {
console.log('등록된 상품이 없습니다.');
}
// 1-2) 방법 2 : export 키워드를 별도로 사용
function edit() {
console.log('상품을 수정합니다.');
}
function del() {
console.log('상품을 삭제합니다.');
}
// 여러 개 내보내기
export { edit, del };
2. default export
[2. default export]
: 기본 내보내기 방식
: 한 모듈 내 하나만 default 지정
[2. 'default 내보내기'를 가져오기] ----------------------
<<문법>>
import 이름 from '경로/파일명.확장자';
: {} 반드시 생략, {} 사용하면 error
: 이름 변경 가능
p240530/module/item.js
// 2-1) 방법 1
import add from './item.js';
import Add from './item.js';
import zzz from './item.js';
add();
Add();
zzz();
// 2-2) 방법 2 : default 키워드를 별도로 사용
// 이런 형태가 많이 사용
// 함수 정의를 먼저 하고 나중에 export 하니까 편함
function add() {
console.log('상품이 등록되었습니다.');
}
// 한 파일 내에 default 내보내기는 1개만 가능
// export default function aaa () {}
export default add;
// 2-3) 방법 3 : 익명 함수
// 가져올 때 이름을 변경할 수 있기 때문에 익명 함수도 많이 사용
export default () => console.log('상품이 등록되었습니다.');
p240530/module/hide.js
console.log('*** hide.js 시작 ***');
function show() {
console.log('>> show() 실행 ')
}
// export default show;
export { show as default }; // 요즘은 잘 사용 x
console.log('*** hide.js 시작 ***');
p240530/module/index.js
import add from './item.js';
import Add from './item.js';
import zzz from './item.js';
add();
Add();
zzz();
// 변수에 저장안하고 파일/모듈 만 실행하겠다는 뜻
import './hide.js';
// 같은 모듈을 다른 형태로 import 해도 한번만 실행
// import * as hide from './hide.js';
// default export 가져오기
import show from './hide.js';
import { default as showTwo } from './hide.js';
show();
showTwo();
모듈 다시 내보내기
- 모듈의 보안 유지 가능
p240530/module/hide.js
console.log('*** hide.js 시작 ***');
function show() {
console.log('>> show() 실행 ')
}
// export default show;
export { show as default }; // 요즘은 잘 사용 x
console.log('*** hide.js 시작 ***');
p240530/module/login.js
console.log('*** login.js 파일 시작 ***');
function login() {
console.log('>>> login() 실행 !!!')
}
export default login;
console.log('*** login.js 파일 종료 ***');
p240530/module/secret.js
console.log('*** secret.js 시작 ***');
// hide 모듈 읽고 바로 내보내기
import Secret from './hide.js';
// login 모듈 읽고 바로 내보내기
import Login from './login.js';
// export default Secret, Login;
export { Secret, Login };
console.log('*** secret.js 종료 ***');
p240530/module/index.js
import { Secret, Login } from './secret.js';
Secret();
Login();
'Language > HTML & CSS & JavaScript' 카테고리의 다른 글
[프로젝트] 행복한 마켓 - 1. HTML, CSS 설정 (0) | 2024.05.29 |
---|---|
[JavaScript] innerText 와 innerHTML 차이점 (0) | 2024.05.28 |
[HTML/CSS] float 을 활용하여 ul 태그로 메뉴 레이아웃 잡기 (0) | 2024.05.16 |
[HTML/CSS] float 을 활용하여 레이아웃 잡고, 해제하기 (0) | 2024.05.16 |
[HTML/CSS] table 태그로 테이블 만들고 style 적용하기 (0) | 2024.05.16 |
JavaScript
- ECMA 스크립트 (ES)
- 객체 기반의 스크립트 프로그래밍 언어 (지향보다는 기반)
- 웹 프로그래밍 언어
- 처음엔 server 가 아닌 client 쪽에서 처리하고 싶어서 언어가 만들어졌는데,
가볍고 용량이 적다 보니 server 쪽에서도 사용 가능해져서 server 쪽도 사용하게 됨 - 동적
- 함수 기반의 언어
- html 을 하나의 객체로 보고, 참조변수를 통해 접근 ==>html 을 document(참조 변수) 를 통해 접근
- 구문이 맞지 않아도 에러가 뜨지 않아서 어디 부분이 에러인지 구분 하기 어려움
JavaScript 특징
- html 에 head / body 에 넣을 수 있는데 보통 body 내에 들어감
- 컴파일 없이 한줄 한줄 해석하며 바로 명령어를 실행하는 인터프리터 언어 HTML의 특정 요소를 선택하여 다양한 이벤트 ( 마우스 클릭, 키보드 입력 등 )에 따라 어떤 동작을 하도록 기능을 넣을 수 있음
JavaScript 사용 방법
내부 스크립트
# p240517/ex01.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>[JavaScript] 방식 1. 내부 스크립트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script>
document.write("내부 스크립트입니다.");
</script>
<h1>JavaScript File</h1>
</body>
</html>
외부 스크립트
# p240517/js/test.js
document.write("외부 파일입니다.");
# p240517/ex02.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>[JavaScript] 방식 2. 외부 스크립트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 방법 1. -->
<!-- head 에 넣어주었지만, 실행 결과는 body 에 보여짐 -->
<!-- <script src="js/test.js"></script> -->
</head>
<body>
<!-- 방법 2. -->
<script src="js/test.js"></script>
<h1>JavaScript File</h1>
<!-- 방법 3. -->
<script src="js/test.js"></script>
</body>
</html>
JavaScript Error !
- 인터프리터 언어라 특정 라인에 에러가 생기면 멈춘다

JavaScript 변수(Variable) 선언 방법
- var -> 선언 위치에 따라 다르지만 보통 전역 변수, 기본값이라 생략 가능, var 변수에 함수를 저장하고 다시 값을 저장하면 변경될 위험이 있어 사용하지 않음
- let -> 블랙 라벨, 전역에 선언된 let 은 global 영역이 아닌 script 영역으로 들어감
- const -> java의 final 와 결이 비슷
- 하나의 코드를 작성할 때 (;) 를 넣는데, 생략해도 에러 발생 x
- 초기화하지 않았으면 undefined 값이 보여짐
- undefined 는 초기화를 하지 않았다는 뜻, null 과 전혀 다름
# p240522/hoisting.html
[var, let, const]
- var 는 함수 레벨 스코프, let 과 const 는 블랙 레벨 스코프
- var 는 선언된 변수를 선언 전에 접근 가능
- let 과 const 는 불가능 (error)
- var 는 이미 선언된 이름과 같은 이름의 변수를 여러 개 선언 가능 (덮어 씌워짐)
- let 과 const 는 불가능 (error)
- var 와 let 은 변수 선언과 동시에 초기화를 하지 않아도 되지만,
const 는 반드시 초기값을 설정해야 함
- var 와 let 은 값 변경이 가능하지만,
const 는 값 변경 불가능
var 는 기본적으로 global 영역에 들어오는데 function 에서 정의하면 지역변수가 됨
var a; // 한개씩 선언
let b;
var a, i; // 동시에 선언
var sum = 0; // 선언과 초기화
let i=0, sum=10, message="Hello"; // 동시에 선언과 초기화
var num;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
num = 100;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
num = 5n;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br>");
# <실행 결과>
num >> undefined
num type >>undefined
num >> 100
num type >>number
num >> 5
num type >> bigint
변수의 데이터 타입
# p240517/type01.html
[ 기본 타입 ] 자료형 Primitive Type
- number : 숫자(정수, 실수)
모든 숫자를 실수로 처리
화면에 소수점이 표현 되지 않아 그렇게 보이지 않음
- bigint : 정수 [ -(2의 53승-1) ~ (2의 53승-1) ]
- string : 문자열
"" or '' 사용 가능
- underfined : 초기화되지 않은 상태, 변수 초기화에 사용
- null : 객체 변수 초기화 사용
- NaN : Not a Number
1 . 변수에 아무런 값을 넣지 않았을 때
<script>
var num;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> undefined
num type >>undefined
2. 변수에 숫자(정수/실수) 넣었을 때
<script>
num = 100;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 100 // 100.0 으로 나오지만 화면엔 그렇게 안나옴
num type >>number
3. 변수에 정수값 넣었을 때
<script>
num = 5n;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 5
num type >>bigint
4. 변수에 문자열 넣었을 때
<script>
num = '하이';
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> 하이
num type >>string
5. 변수에 boolean 넣었을 때
<script>
num = true;
document.write("num >> " + num);
document.write("<br>");
document.write("num type >>", typeof num);
document.write("<br> <br>");
</script>
# 실행 결과
num >> true
num type >>boolean
문자열 리터럴
# p240517/type02.html
[문자열]
* 템플릿 리터럴 : 백틱 사용
: 이중 따옴표나 작은 작은표 대신 백틱(`)을 사용해서 표현
: 작은 따옴표와 혼동할 수 있으나, 백틱은 일반적으로 키보드 tab 키 위에 있음
: 플래이스 홀더를 이용한 &{expression} 으로 표현식 사용ㅇ

문자열 관련 함수
# p240517/type03.html
문자열 길이 : length()
<script>
// string 의 참조변수 today
// string = 객체
const today = 'Good~';
// 문자열 길이
console.log('문자열 길이 >> ' + today.length); # 문자열 길이 >> 5
</script>
특정 문자 변경 : replace(변경할 문자, 대체할 문자)
1) 일치하는 첫 번째만 변경
2) 일치하는 모두 변경
<script>
const today = 'Good~';
// - 일치하는 첫 번째만 변경
console.log(today.replace('o', 'ap-'));
// - 일치하는 모두 변경
console.log(today.replaceAll('o', 'ap-'));
</script>
# 실행 결과
Gap-od~
type03.html:27 Gap-ap-d~
특정 위치의 문자 추출
1) 문자열 .substring(시작 인덱스, 끝 인덱스)
<script>
const today = 'Good~';
// 1. 문자열.substring (시작 인덱스, 끝 인덱스)
console.log(today.substring(1, 4));
console.log('음수 인덱스 : ' + today.substring(1, -1)); // 처리 못함(지원안됨)
</script>
# 실행 결과
ood
음수 인덱스 : G
2) 문자열 .slice(시작 인덱스, 끝 인덱스)
<script>
const today = 'Good~';
// 2. 문자열.slice(시작 인덱스, 끝 인덱스)
console.log(today.slice(1, 5));
console.log(today.slice(1, -1));
console.log(today.slice(1)); // 시작 인덱스부터 끝까지
console.log(today.slice(-4));
console.log('-4 ~ 0 : ' + today.slice(-4, 0)); // 잘못됨
</script>
# 실행 결과
ood~
ood
ood~
ood~
-4 ~ 0 :
특정 문자 기준으로 분리(쪼개기) : split(특정 문자)
- 배열로 리턴
- 기준으로 사용된 문자는 요소에 없음
<script>
const today = 'Good~';
console.log(today.split('d'));
</script>
# 실행 결과
(2) ['Goo', '~']
특정 문자 추가 : 문자열.padStart(문자열 전체 길이, 추가할 문자)
<script>
const today = 'Good~';
// 문자열.padStart(문자열 전체 길이, '추가할 문자')
console.log(today.padStart(10, '*'));
console.log(today.padEnd(10, '*'));
</script>
# 실행 결과
*****Good~
Good~*****
특정 문자 찾기 : include(찾고자 하는 문자열) => true / false 리턴
<script>
const today = 'Good~';
console.log('d : ' + today.includes('d'));
console.log('G : ' + today.includes('G'));
console.log('Go : ' + today.includes('Go'));
console.log('go : ' + today.includes('go'));
</script>
# 실행 결과
d : true
G : true
Go : true
go : false
특정 문자의 위치(index) 리턴 : indexof(찾고자하는 문자열)
- 있음 : 탐색된 첫 번째 문자의 인덱스 리턴
- 없음 : -1 리턴
<script>
const today = 'Good~';
console.log(today.indexOf('o'));
console.log(today.indexOf('Go'));
console.log(today.indexOf('d'));
console.log(today.indexOf('H'));
</script>
# 실행 결과
1
0
3
-1
문자 반복 : repaeat(반복할 횟수)
<script>
const today = 'Good~';
console.log(today.repeat(3));
console.log('홍길동'.repeat(3));
</script>
# 실행 결과
Good~Good~Good~
홍길동홍길동홍길동
대/소문자 변경
<script>
const today = 'Good~';
console.log(today.toUpperCase());
console.log(today.toLowerCase());
</script>
# 실행 결과
GOOD~
good~
공백 제거
<script>
const say = ' hi ~ ! ';
console.log(say);
console.log('|' + say + '|');
console.log('|' + say.trimStart() + '|'); // 왼쪽 공백 제거
console.log('|' + say.trimEnd() + '|'); // 오른쪽 공백 제거
console.log('|' + say.trim() + '|'); // 양쪽 공백 제거
</script>
# 실행 결과
hi ~ !
| hi ~ ! |
|hi ~ ! |
| hi ~ !|
|hi ~ !|
참조 타입 - 배열
# p240517/type04.html
<script>
// [배열]
var arr = [2, 4, 2.5, 'ㅎㅇ'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[3]);
console.log('arr 타입 : ', typeof arr); // object , 배열로 출력되지만 타입은 object 로 보여짐
console.log('arr[0] 타입 : ', typeof arr[0]);
</script>
# 실행 결과
Array(4)
2
4
ㅎㅇ
arr 타입 object
arr[0] 타입 number
<script>
// 배열의 요소에 배열로 와도 상관 x
var arr2 = [arr, 3, '즐거운 하루'];
console.log(arr2);
console.log('arr2[0] : ' + arr2[0]);
console.log('arr2[0] : ' + arr2[0][2]);
console.log('하루 추출 : ' + arr2[2].slice(-2));
</script>
# 실행 결과
Array(3)
arr2[0] : 2,4,2.5,ㅎㅇ
arr2[0] : 2.5
하루 추출 : 하루
참조 타입 - 객체
# p240517/type04.html
<script>
// [객체]
// [property(요소)] {key: value};
// 순서 보장 x ==> index 개념 없고, key 값으로 찾기
var obj = {
name : '홍길동',
age : 35,
};
console.log(obj);
console.log('obj 타입 : ' + typeof obj);
// [property(요소) 접근] 방법 1
// : 점 접근
// : key 그대로 사용
console.log('name 값 출력 : ', obj.name);
// [property(요소) 접근] 방법 2
// : [] 접근
// : key를 문자열 취급하여 사용
console.log('name 값 출력 : ', obj['name']);
</script>
# 실행 결과
Object
obj 타입 : object
name 값 출력 : 홍길동
name 값 출력 : 홍길동
배열 관련 함수(type05,06)
# p240517/type05.html
<script>
// 배열을 내부적으로 객체 형태로 관리
// index 또는 key 로 봄
// const 인데 추가/삭제가 되는 이유는 ?!
// : 주소가 오기 때문에 크게 문제가 없음
const even = [2, 4, 6];
console.log(even);
console.log('even[0] : ' + even[0]);
console.log('even[2] : ' + even[2]);
// [property(요소) 추가]
// 1) 맨 뒤에 추가
even.push(8);
console.log('1) 요소 1개 맨 뒤 추가 : ' + even);
even.push(10, 12);
console.log('1) 요소 2개 맨 뒤 추가 : ' + even);
// 2) 맨 앞에 추가
even.unshift(-2);
console.log('2) 요소 1개 맨 앞 추가 : ' + even);
even.unshift(-4, -6);
console.log('2) 요소 2개 맨 앞 추가 : ' + even);
// [property(요소) 삭제]
// 1) 맨 뒤에서 삭제
console.log('현재 even : ' + even);
const pop1 = even.pop();
const pop2 = even.pop();
console.log('pop1 : ' + pop1);
console.log('pop2 : ' + pop2);
// 2) 맨 앞에서 삭제
console.log('현재 even : ' + even);
const shift1 = even.shift();
const shift2 = even.shift();
console.log('shift1 : ' + shift1);
console.log('shift2 : ' + shift2);
</script>
# 실행 결과
Array(5)
even[0] : 2
even[2] : 6
1) 요소 1개 맨 뒤 추가 : 2,4,6,8
1) 요소 2개 맨 뒤 추가 : 2,4,6,8,10,12
2) 요소 1개 맨 앞 추가 : -2,2,4,6,8,10,12
2) 요소 2개 맨 앞 추가 : -4,-6,-2,2,4,6,8,10,12
현재 even : -4,-6,-2,2,4,6,8,10,12
pop1 : 12
pop2 : 10
현재 even : -4,-6,-2,2,4,6,8
shift1 : -4
shift2 : -6
p240517/type06.html
<script>
const odd = [1, 3, 5];
console.log('odd >> ' + odd);
console.log('\n');
// [문법] 배열.slic(시작 인덱스, 끝 인덱스)
// : 시작 인덱스에서 끝 인덱스 포함 전까지 자른 배열 리턴
copy_odd = odd.slice(0, 2);
console.log('copy_odd >> ' + copy_odd);
console.log('odd >> ' + odd);
console.log('\n');
// -2 인덱스에서 끝까지
copy_odd_two = odd.slice(-2);
console.log('copy_odd_two >> ' + copy_odd_two);
console.log('odd >> ' + odd);
console.log('\n');
// 추가, 삭제
// splice(스플라이스)
// [문법] 배열.splice(시작 인덱스, 개수, 추가요소1, 추가요소2)
// : 3번째 요소(추가요소1)부터 추가
// [문법] 배열.splice(start, deleteCount) : 시작 인덱스에서 개수만큼 요소 삭제
// 추가
odd.splice(-1, 0, '칠');
console.log('추가한 odd >> ' + odd);
console.log('\n');
// 삭제
odd.splice(1, 1);
console.log('삭제한 odd >> ' + odd);
console.log('\n');
// 추가
odd.splice(0, 1, '하나');
console.log('추가한 odd >> ' + odd);
odd.splice(0, 2, '하나', '둘', '셋');
console.log('추가한 odd >> ' + odd);
console.log('\n');
// [배열 요소 추가]
// [문법] 배열.concat(추가할 요소, 추가할 배열, ...)
console.log('현재 odd >> ' + odd);
concat_odd = odd.concat(7, 9); // 복사본을 변수에 저장
console.log('concat_odd >> ' + concat_odd);
console.log('odd >> ' + odd);
console.log('\n');
// 인수로 배열을 추가했지만, 배열의 요소가 추가됨
concat_odd2 = odd.concat([11, 12]);
console.log('concat_odd2 >> ' + concat_odd2);
console.log('odd >> ' + odd);
console.log('\n');
/* [특정 요소 찾기(탐색)]
[문법]
1) 배열.indexOf(item, from); : 인덱스 from 부터 시작해서 item 탐색
: 있으면 index 리턴, 없으면 -1 리턴
2) 배열.lastIndexOf(item, from) : 마지막 인덱스부터 item 탐색
: 있으면 index 리턴, 없으면 -1 리턴
3) 배열.includes(item, from) : 인덱스 from 부터 시작해서 item 탐색
: 있으면 true 리턴, 없으면 false 리턴
*/
arr = [1, 10, false, NaN, null, 10];
console.log('[있는 값] 10 찾아라 !');
console.log('indexOf : ' + arr.indexOf(10));
console.log('lastIndexOf : ' + arr.lastIndexOf(10));
console.log('includes : ' + arr.includes(10));
console.log('\n');
console.log('[없는 값] 2 찾아라 !');
console.log('indexOf : ' + arr.indexOf(2));
console.log('lastIndexOf : ' + arr.lastIndexOf(2));
console.log('includes : ' + arr.includes(2));
console.log('\n');
console.log('[있는 값] false 찾아라 !');
console.log('indexOf : ' + arr.indexOf(false));
console.log('lastIndexOf : ' + arr.lastIndexOf(false));
console.log('includes : ' + arr.includes(false));
console.log('\n');
console.log('[있는 값] null 찾아라 !');
console.log('indexOf : ' + arr.indexOf(null));
console.log('lastIndexOf : ' + arr.lastIndexOf(null));
console.log('includes : ' + arr.includes(null));
console.log('\n');
console.log('[있는 값] NaN(Not a Number) 찾아라 !');
console.log('indexOf : ' + arr.indexOf(NaN));
console.log('lastIndexOf : ' + arr.lastIndexOf(NaN));
console.log('includes : ' + arr.includes(NaN));
console.log('\n');
</script>
# 실행 결과
odd >> 1,3,5
copy_odd >> 1,3
odd >> 1,3,5
copy_odd_two >> 3,5
odd >> 1,3,5
추가한 odd >> 1,3,칠,5
삭제한 odd >> 1,칠,5
추가한 odd >> 하나,칠,5
추가한 odd >> 하나,둘,셋,5
현재 odd >> 하나,둘,셋,5
concat_odd >> 하나,둘,셋,5,7,9
odd >> 하나,둘,셋,5
concat_odd2 >> 하나,둘,셋,5,11,12
odd >> 하나,둘,셋,5
[있는 값] 10 찾아라 !
indexOf : 1
lastIndexOf : 5
includes : true
[없는 값] 2 찾아라 !
indexOf : -1
lastIndexOf : -1
includes : false
[있는 값] false 찾아라 !
indexOf : 2
lastIndexOf : 2
includes : true
[있는 값] null 찾아라 !
indexOf : 4
lastIndexOf : 4
includes : true
[있는 값] NaN(Not a Number) 찾아라 !
indexOf : -1
lastIndexOf : -1
includes : true
객체 축약 표현
1. 키와 값이 같은 경우
# p240517/type07.html
<script>
// 객체 형태
const obj = {
key : '값', // property
};
// 1. 키와 값이 같은 경우
const name = '박보검';
const age = 30;
// 1-1. 키와 값을 모두 설정
// const info = {
// name : name,
// age : age,
// };
// 1-2. 축약 표현
// : 키와 값이 같다면, 값 생략 가능
const info = {name, age};
console.log(info);
console.log('객체 info 의 property name >> ', info.name);
console.log('객체 info 의 property name >> ', info['name']);
</script>
# 실행 결과
Object
객체 info 의 property name >> 박보검
객체 info 의 property name >> 박보검
2. 값이 함수인 경우
# p240517/type07.html
<script>
// 2. 값이 함수인 경우
// 익명 함수, 이름이 있는 거 자체가 의미가 없음
// hello() -> 생략 가능
// 2-1. 원래 형태
// const say = {
// hi : function () {
// console.log('ㅎㅇ 반가룽 ~');
// }
// }
// 2-2. 축햑 형태
const say = {
hi () {
console.log('ㅎㅇ 반가룽 ~')
},
nickname : '홍길동',
}
say.hi(); // hi 가 key
console.log('닉네임 : ', say.nickname);
</script>
객체 함수(type08)
# p240517/type08.html
<script>
const number = {
one : 1,
two : 2,
three : 3,
};
console.log(number);
console.log('key 를 배열로 출력 : ' + Object.keys(number));
console.log('value 를 배열로 출력 : ' + Object.values(number));
console.log('key 와 value 를 하나의 쌍으로 출력 : ' + Object.entries(number));
</script>
# 실행 결과
Object
key 를 배열로 출력 : one,two,three
value 를 배열로 출력 : 1,2,3
key 와 value 를 하나의 쌍으로 출력 : one,1,two,2,three,3
객체 구조 분해 할당 - 1
# p240520/ex01.html
- 배열이나 객체의 속성을 해체하여 개별 변수에 저장
배열
1-1) 변수 개수 = 배열의 요소 개수
// 1-1) 변수 개수 = 배열의 요소 개수
<script>
const even = [2, 4];
const [a, b] = even;
console.log('a >> ' + a); // tyep : 문자열
console.log('b >> ', b); // tyep : 문자열 + object
</script>
# 실행 결과
a >> 2
b >> 4
1-2) 변수 개수 < 배열의 요소 개수
// 1-2) 변수 개수 < 배열의 요소 개수
<script>
console.log("1-2) 변수 개수 < 배열의 요소 개수");
const odd = [1, 3, 5, 7, 9];
const [c, d, ...rest] = odd ;
console.log('c >> ' + c);
console.log('d >> ' + d);
console.log('rest >> ' + rest);
</script>
# 실행 결과
c >> 1
d >> 3
rest >> 5,7,9
1-3) 변수 개수 > 배열의 요소 개수
// 1-3) 변수 개수 > 배열의 요소 개수
<script>
console.log("1-3) 변수 개수 > 배열의 요소 개수");
var [e, f, g] = even;
console.log(e, f, g); // g : undefined
</script>
# 실행 결과
2 4 undefined
초기값 설정
// 초기값 설정
<script>
var [h=10, i=9, j=8] = even;
console.log(h, i, j);
console.log('even >> ' + even);
</script>
# 실행 결과
2 4 8
even >> 2,4
객체
<script>
console.log("2-1) 객체 값 가져오기");
const info = {
nickname : '홍길동',
age : 25,
}
// 변수명 과 키명과 같지 않으면 값이 할당이 안됨
// var { hi, age } = info;
// console.log('hi >>', hi); // hi >> undefined
// 순서 상관 x
var { nickname, age } = info;
var { age, nickname } = info;
console.log('nickname >>', nickname);
console.log('age >>', age);
</script>
# 실행 결과
nickname >> 홍길동
age >> 25
<script>
var { new_nickname, new_age } = info;
console.log('new_nickname >>', new_nickname); // undefined
console.log('new_age >>', new_age); //undefined
var { nickname : new_nickname, age : new_age } = info;
console.log('new_nickname >>', new_nickname);
console.log('new_age >>', new_age);
</script>
# 실행 결과
new_nickname >> undefined
new_age >> undefined
new_nickname >> 홍길동
new_age >> 25
객체 구조 분해 할당 - 2
# p240520/ex02.html
1) 매개변수 : 1개
<script>
const info = { nickname : '홍길동', age : 25 };
// 1) 매개변수 : 1개
function show_info(args) { // 타입 지정 x, 반환형 x
// console.log(args);
console.log("nickname >>", args.nickname);
console.log("age >>", args.age);
}
console.log('\n');
// 함수 호출
show_info(info);
</script>
2) 매개변수 : 2개
<script>
const info = { nickname : '홍길동', age : 25 };
// 2) 매개변수 : 객체의 구조분해
{ nickname, age } = { nickname:nickname, age:age } 값이 생략된 것
function show_info({ nickname, age }) {
console.log("nickname >>", nickname);
console.log("age >>", age);
}
// 함수 호출
show_info(info);
</script>
2-1) 매개변수 : 객체의 구조분해
<script>
const info = { nickname : '홍길동', age : 25 };
// 2-1) 매개변수 : 객체의 구조분해
// -> 변수명을 원하는 변수명으로 지정
function show_info({ nickname:new_nickname , age:new_age }) {
console.log("nickname >>", new_nickname);
console.log("age >>", new_age);
}
// 함수 호출
show_info(info);
</script>
연산자
# p240520/operator-ex01.html
- 산술 연산자 : + - * **(제곱) / %
- 대입 연산자 : =
- 복합대입 연산자 : += -= *= /= %=
- 증감 연산자 : ++ --
- 관계 연산자 : > >= < <=
== != 값만 비교
=== !== 값과 타입 비교
- 논리 연산자 : && || !
- 삼항 연산자 : 조건 ? 참 : 거짓
- 널리쉬(nullish) : 변수 ?? 변수 ?? 변수
여러 개의 피연산자 중 값이 확정된 변수 찾음
null, undefined 제외
- 전개 연산자 : ...배열명
반복 가능한 데이터(배열 요소)를 펼침
산술 연산자
<script>
var n1 = 5;
var n2 = 3;
console.log('제곱 :', n1 ** n2);
console.log('곱하기: ', n1 * n2);
</script>
# 실행결과
제곱 : 125
곱하기: 15
복합대입 연산자
<script>
var n1 = 5;
var n2 = 3;
console.log('n1 **= n2 :', n1);
</script>
# 실행결과
n1 **= n2 : 125
증감 연산자
<script>
var n1 = 5;
var n2 = 3;
n2--;
console.log('후감소 :', n2);
</script>
# 실행결과
후감소 : 2
관계 연산자
<script>
var n3 = 5;
var n4 = '5';
console.log('n3 type :', typeof n3);
console.log('n4 type :', typeof n4);
console.log('n3 == n4 :', n3 == n4);
console.log('n3 === n4 :', n3 === n4);
</script>
# 실행결과
n3 type : number
n4 type : string
n3 == n4 : true
n3 === n4 : false
논리 연산자
<script>
var n3 = 5;
console.log('!true :', !true);
console.log('!n3 :', !n3);
console.log('!-5 :', !-5);
console.log('!0 :', !0);
console.log('!2.5 :', !2.5);
</script>
# 실행결과
!true : false
!n3 : false
!-5 : false
!0 : true
!2.5 : false
삼항 연산자
<script>
var n3 = 5;
var n4 = '5';
var result = (n3 === n4) ? "값이 같다" : "값과 타입이 다르다"
console.log("result :", result)
// (n3 === n4) ? console.log('같다') : console.log('다르다');
</script>
# 실행결과
result : 값과 타입이 다르다
널리쉬(nullish)
// 값이 두개인 경우 앞에 있는 값이 저장되고, 나머지는 순회 x
// 값이 없는 경우 나머지 값을 넣음(null or underfined)
<script>
var n4 = null;
var n5 = null;
var n6 = undefined;
var value = n6 ?? n5 ?? n4;
console.log("value :", value);
</script>
# 실행결과
value : null
전개 연산자, 전개 구문(spread sysntax)
<script>
var even = [2, 4, 6];
console.log('even >>', even);
console.log('even : 전개 연산자 >>', ...even);
var odd = [1, 3, 5];
var number = [even, odd];
// 배열안에 배열이 들어올 때
console.log('number >>', number);
// 배열안에 배열의 요소가 들어오고 싶을 때
var spread_number = [...even, ...odd];
console.log('spread_number >>', spread_number);
</script>
# 실행결과
even >> (3) [2, 4, 6]
even : 전개 연산자 >> 2 4 6
number >> (2) [Array(3), Array(3)]
spread_number >> (6) [2, 4, 6, 1, 3, 5]
대화상자(dialog-box)
1. 경고창 => 사용자에게 경고하기 위해서
2. 확인창 => 사용자에게 2 중의 답을 알기 위해서 (true/false)
3. 입력창 => 사용자에게 입력받기 위해서
1. 경고창
# p240520/dialog-box-alert.html
<script>
// ip:port 내용
// 순서 : h1 > '1번째 출력' > alert > '2번째 출력'
// 특정 라인에서 코드 멈추기 : breakpoint
// 중지점은 태그랑 상관 x
// 단계별 실행 : F8
document.write('1번째 출력<br>');
var answer = alert("경고창입니다."); // undefined
document.write('answer >> ', answer)
document.write('<br>2번째 출력');
</script>


2. 확인창
# p240520/dialog-box-confirm.html
// 사용자가 무엇을 눌렀는지 확인할 수 있음
<script>
var answer = confirm('입력을 완료했나요 ?');
document.write(answer); // true or false
</script>

★ 확인창 퀴즈 !
[문제]
true 와 false 는 변수를 사용해서 쓰기
확인 버튼을 클릭하면,
'리턴값은 true 이고, 확인을 클릭했습니다.' 를 화면에 출력
취소 버튼을 클릭하면,
'리턴값은 false 이고, 취소를 클릭했습니다.' 를 화면에 출력
<script>
var answer = confirm('입력을 완료했나요 ?');
// [방법 1]
var check = (answer) ? "확인" : '취소';
document.write(`리턴값은 ${answer}이고, ${check}을/를 클릭했습니다.`);
// [방법 2]
if (answer) {
document.write(`리턴값은 ${answer}이고, 확인을 클릭했습니다.`);
} else {
document.write(`리턴값은 ${answer}이고, 취소를 클릭했습니다.`);
}
</script>
3. 입력창
# p240520/dialog-box-prompt.html
<script>
// 아무런 입력도 안했을 때 --> 빈문자열
// 취소 버튼 눌렀을 때 --> null
var answer = prompt('오늘 날씨는 ?');
document.write('답변 ... ', answer);
</script>
★ 입력창 퀴즈 !
[문제]
prompt 함수를 이용하여, 정수 1개 입력 받은 후 1 증가된 값 출력
prompt 문구 : 정수 1개 입력하세요. 6
화면 출력 : 1 증가한 값 6 입니다.
<script>
var userNumber = prompt('정수 1개 입력하세요.');
userNumber++;
document.write(`1 증가한 값 ${userNumber} 입니다.`);
</script>


<script>
var userNumber = prompt('정수 1개 입력하세요.');
document.write('userNumber type : ' + typeof userNumber);
document.write('<br>');
userNumber++;
document.write('[자동형변환] userNumber type : ' + typeof userNumber);
document.write('<br>');
// 방법 1
userNumber = parseInt(userNumber) + 1;
document.write('[강제형변환 1번] userNumber type : ' + typeof userNumber);
document.write('<br>');
// 방법 2
userNumber = Number(userNumber) + 1;
document.write('[강제형변환 2번] userNumber type : ' + typeof userNumber);
document.write('<br>');
document.write(`1 증가한 값 ${userNumber} 입니다.`);
</script>
제어문 : 조건문, 반복문
1-1. 조건문 : swith문
# p240520/swith.html
[특이점]
- 자바는 정수만 올 수 있는데, 자바스크립트는 실수도 올 수 있음
<script>
var data = 2.5;
var one = 1;
switch(data) {
case one:
document.write('1이다.');
break
case 2:
document.write('2이다.');
break
case 2.5:
document.write('2.5이다.');
break
default:
document.write('기타');
}
</script>
1-2. 조건문 : if문
# p240520/if.html
[문법]
# 조건 1개
if (조건식) {
명령어;
명령어;
}
# 조건 2개
if (조건식) {
true일 때 명령어;
} else {
false 일 때 명령어;
}
# 조건 3개
if (조건식 1) {
명령어;
} else if (조건식 2) {
명령어;
} else if (조건식 3) {
명령어;
}
<script>
var num = 3;
// num % 2 값이 0 또는 1인데
// if (1) 이 되면 자바스크립트가 자체적으로 논리값으로 변환하여
// true 또는 false 됨 (좋은 형태는 아니지만, 문법상 가능)
if (num % 2 ==1) {
document.write('홀수');
} else {
document.write('짝수');
}
</script>
2-1. 반복문: for문
# p240520/for.html
[문법]
: for문 안에서 변수 선언할 거면 var 보다는 let(지역변수)를 쓰는 것이 좋음
for (let 초기값; 조건식; 증감식)
for (초기값; 조건식; 증감식) {
명령어;
}
<script>
// var num = 1;
for (let num=1; num<11; num++) {
document.write(num);
document.write('<br>');
}
</script>
2-2. 반복문: for in문
# p240520/for-in.html
[문법]
: 초기값, 증감식 x
: property 의 key 를 추출
for (let 변수 in 객체) {
명령어;
}
<script>
var arr = [1, 3, 5, 7, 9];
document.write("arr 배열의 길이 >> ", arr.length); // arr 배열의 길이 >> 5
document.write("<br>");
// 웹 브라우저로 출력
for (let n in arr) {
document.write(n + ' '); // 0 1 2 3 4
}
document.write("<br>");
// console 창으로 출력
console.log("arr >> ", arr); // arr >> (5) [1, 3, 5, 7, 9]
for (let n in arr) {
console.log(n);
}
var obj = { nickname : '홍길동', age : 25 }
// << for-in문 >>
for (let key in obj) {
document.write(key + ' '); // nickname age
}
</script>
2-3. 반복문: for of문
# p240520/for-of.html
[문법]
: property 의 value 를 추출
: Symbol.iterator property 를 가진 반복 가능한 객체에서만 사용 가능
: 배열에서 가능
for (let 변수 of 객체) {
명령어;
}
<script>
var arr = [1, 3, 5, 7, 9];
for (let i of arr) {
document.write(i + ' '); // 1 3 5 7 9
}
document.write('<br>');
var obj = { nickname : '홍길동', age : 25 };
// console.log(obj);
// for (let value of obj) {
// document.write(value + ' ');
// }
</script>
https://jongbeom-dev.tistory.com/139
[JavaScript] iterable, iterator
iterable 객체란 Iterable 객체란 Symbol.iterator라는 Symbol 타입의 값을 속성으로 가지고 그 속성의 값이 인자를 받지 않으며 iterator 객체를 반환하는 메소드인 객체를 의미한다. 배열은 대표적인 iterable
jongbeom-dev.tistory.com
2-4. 반복문: while문
while문 : 기본
# p240520/while-ex01.html
[문법]
초기값;
while (조건식) {
명령어;
증감식;
}
for (let 변수 of 객체) {
명령어;
}
<script>
var num = 1;
while (num < 11) {
document.write(num);
document.write('<br>');
num++;
}
</script>

while문 : 무한루프
# p240520/while-ex02.html
<!-- while 문을 무한 루프로 구현하여, 1 ~ 10 을 출력 -->
<script>
var idx = 1;
while (true) {
document.write(idx);
document.write('<br>');
if (idx == 10) {
break
}
idx++;
}
</script>
2-5. 반복문: do~while문
# p240520/do-while.html
<script>
var num = 1;
do {
document.write(num);
document.write('<br>');
num++;
} while (num < 11)
</script>
함수 : 내장 함수, 사용자 정의 함수
1. 내장 함수 : 이미 정의된 함수
# p240520/function-ex01.html
<script>
// eval : 문자열로 표현된 식을 계산하는 함수
var sum = eval('1 + 2 + 3');
document.write('덧셈 결과 : ', sum);
// 형변환 : 정수
document.write('문자열을 정수로 변환 >> ', parseInt('5'));
document.write('문자열을 정수로 변환 : type >> ', typeof parseInt('5'));
document.write('실수를 정수로 변환 : type >> ', parseInt(5.23));
document.write('실수를 정수로 변환 : type >> ', typeof parseInt(5.23));
// 형변환 : 실수
document.write('문자열을 실수로 변환 >> ', parseFloat('5.25'));
document.write('문자열을 실수로 변환 : type >> ', typeof parseFloat('5.25'));
document.write('정수를 실수로 변환 : type >> ', parseFloat(5));
</script>
# 실행 결과
eval
덧셈 결과 : 6
형변환 : 정수
문자열을 정수로 변환 >> 5
문자열을 정수로 변환 : type >> number
실수를 정수로 변환 : type >> 5
실수를 정수로 변환 : type >> number
형변환 : 실수
문자열을 실수로 변환 >> 5.25
문자열을 실수로 변환 : type >> number
정수를 실수로 변환 : type >> 5
2. 사용자 정의 함수
[특이점]
: 정의된 메소드 매개변수 수가 달라도 호출 가능하며, 에러가 뜨지 않음
: 타입이 지정되어 있지 않기 때문에 들어오는 값이 한정되어있지 않음
아무런 입력을 안했을 때, underfined 타입이 됨
[함수 정의 형태]
1. 매개변수 있고, 리턴값 있음
2. 매개변수 있고, 리턴값 없음
3. 매개변수 없고, 리턴값 있음
4. 매개변수 없고, 리턴값 없음
<< 함수 정의 >>
function 함수명 (매개변수1, 매개변수2) {
명령어;
return 값;
}
<< 함수 호출 >>
함수명(인수1, 인수2);
[return 의미]
- 함수 실행 끝
- 호풀한 쪽으로 리턴값 넘김
[함수 실행 끝]
- return
- body 의 }
[함수 정의 형태]
# p240520/function-ex02.html
<script>
// 2. [함수 호출]
// : 함수를 정의 전에 호출을 했는데도, 호출이 가능
document.write('2. [함수 호출]<br>');
document.write('[함수 정의 전] 호출');
sum(1, 4);
document.write('<br>');
// 1. [함수 정의]
// : 매개변수 있고, 리턴값 있음
document.write('1. [함수 정의]<br>');
function sum (n1, n2) {
document.write('<br>');
document.write('n1 >> ', n1);
document.write('<br>');
document.write('n2 >> ', n2);
document.write('<br>');
document.write('합 >> ', n1 + n2);
document.write('<br>');
}
document.write('[함수 정의 후] 호출');
sum(2, 9);
document.write('<br>');
// 매개변수 수가 달라도 메소드 호출이 가능
sum(1, 3, 5, 7);
sum(6); // NaN
sum(); // NaN
sum('ㅎㅇ', '홍길동');
sum(2.5, 3.1);
sum(2.5, 5);
sum('ㅎㅇ', 2);
sum('ㅎㅇ'); // 문자열 : ㅎㅇundefined, 이어진 것!
</script>
# 실행 결과
2. [함수 호출]
[함수 정의 전] 호출
n1 >> 1
n2 >> 4
합 >> 5
1. [함수 정의]
[함수 정의 후] 호출
n1 >> 2
n2 >> 9
합 >> 11
n1 >> 1
n2 >> 3
합 >> 4
n1 >> 6
n2 >> undefined
합 >> NaN
n1 >> undefined
n2 >> undefined
합 >> NaN
n1 >> ㅎㅇ
n2 >> 홍길동
합 >> ㅎㅇ홍길동
n1 >> 2.5
n2 >> 3.1
합 >> 5.6
n1 >> 2.5
n2 >> 5
합 >> 7.5
n1 >> ㅎㅇ
n2 >> 2
합 >> ㅎㅇ2
n1 >> ㅎㅇ
n2 >> undefined
합 >> ㅎㅇundefined
[함수 정의 형태] 1. 매개변수 없고, 리턴값 없음
# p240521/function-ex01.html
<script>
// 1-1. [함수 정의] 매개변수 없고, 리턴값 없음
function stringPrint() {
console.log('함수 실행 !');
}
// 1-2. 함수 호출
stringPrint();
stringPrint(2); // 인수를 넣어도 정상적으로 실행이 됨
var reslut = stringPrint(); // 여기까지 호출되지만 저장된 값이 없기 때문에
console.log('reslut >> ', reslut) // reslut 는 undefined 가 됨
</script>
# 실행 결과
함수 실행 !
함수 실행 !
함수 실행 !
reslut >> undefined
[함수 정의 형태] 2. 매개변수 없고, 리턴값 있음
# p240521/function-ex02.html
<script>
// 2-1. [함수 정의] 매개변수 없고, 리턴값 있음
function stringReturn() {
console.log('[함수 실행 시작]') // 확인을 위해 작성
return '즐거운 하루';
console.log('[함수 실행 종료]') // 위 코드에서 return 이 되어 있기 때문에 함수 종료, 의미 x
}
// 2-2. 함수 호출
stringReturn(); // console.log 를 찍은 게 아니라 안보여질 뿐, 호출 실행 됐음
var reslut = stringReturn();
console.log('reslut >> ', reslut);
</script>
# 실행 결과
[함수 실행 시작]
[함수 실행 시작]
reslut >> 즐거운 하루
[함수 정의 형태] 3. 매개변수 있고, 리턴값 없음
# p240521/function-ex03.html
<script>
// 3-2. 함수 호출
// 지역변수, 초기화 할 수 있는게 없어서 undefined 가 됨
info();
info('박보검');
info('홍길동', 25);
info('이미자', 32, '운동'); // 매개변수를 더 받아도 error 가 아님
// 3-1. [함수 정의] 매개변수 있고, 리턴값 없음
// << 특징 >>
// - 매개변수와 인수의 자료형이 동일한지 검사하지 않음
// - 매개변수의 개수와 인수의 개수가 같은지 검사하지 않음
// - 매개변수의 개수가 인수의 개수보다 적으면 undefined 저장
function info(name, value) {
console.log('name >> ', name);
console.log('value >> ', value);
console.log('------------------------------------');
}
</script>
# 실행 결과
name >> undefined
value >> undefined
------------------------------------
name >> 박보검
value >> undefined
------------------------------------
name >> 홍길동
value >> 25
------------------------------------
name >> 이미자
value >> 32
------------------------------------
[함수 정의 형태] 4. 매개변수 있고, 리턴값 있음
# p240521/function-ex03.html
<script>
// 4-2. 함수 호출
// 아래 코드를 보고 자바스크립트는 어떠한 형태든 받는다 라는 것을 알 수 있음
// 주소도 받을 수 있음(객체, 함수, 그 외), 뒤에 가서 배울 예정
var reslut = add(); // add(un.., un..) 매개변수가 없어 undefined 계산이 안되기 때문에
console.log('1. 덧셈 결과 >> ', reslut); // 결과값 NaN
var reslut = add(1); // add(1, un..), 같은 변수명을 써도 문제가 안되고, 덮어씌워짐
console.log('2. 덧셈 결과 >> ', reslut); // 결과값 NaN
var reslut = add(1, 3);
console.log('3. 덧셈 결과 >> ', reslut);
var reslut = add(2, 4, 8);
console.log('4. 덧셈 결과 >> ', reslut); // 매개변수를 더 받아도 error 가 아님
var reslut = add('오늘', '하루');
console.log('5. 덧셈 결과 >> ', reslut); // 문자열 작업, type 은 string
var reslut = add(2.4, 1.2);
console.log('6. 덧셈 결과 >> ', reslut);
var reslut = add(5, 1.2);
console.log('7. 덧셈 결과 >> ', reslut);
// 4-1. [함수 정의] 매개변수 있고, 리턴값 있음
// << 특징 >>
// - 매개변수와 인수의 자료형이 동일한지 검사하지 않음
// - 매개변수의 개수와 인수의 개수가 같은지 검사하지 않음
// - 매개변수의 개수가 인수의 개수보다 적으면 undefined 저장
function add(x, y) {
console.log('======================================');
console.log('매개변수 x : ', x);
console.log('매개변수 y : ', y);
var total = x + y;
return total;
}
</script>
# 실행 결과
매개변수 x : undefined
매개변수 y : undefined
1. 덧셈 결과 >> NaN
====================================
매개변수 x : 1
매개변수 y : undefined
2. 덧셈 결과 >> NaN
====================================
매개변수 x : 1
매개변수 y : 3
3. 덧셈 결과 >> 4
====================================
매개변수 x : 2
매개변수 y : 4
4. 덧셈 결과 >> 6
====================================
매개변수 x : 오늘
매개변수 y : 하루
5. 덧셈 결과 >> 오늘하루
====================================
매개변수 x : 2.4
매개변수 y : 1.2
6. 덧셈 결과 >> 3.5999999999999996
====================================
매개변수 x : 5
매개변수 y : 1.2
7. 덧셈 결과 >> 6.2
Arguments 속성
- 함수가 웹 브라우저에 의해 처리가 될 때 위에서 아래로 처리가 되는데 매개변수가 없는
함수에 인수를 넣어줄 때 함수에서 확인 할 수 있음 (글 정리) - 참조변수를 통해 찾아갈 수 있음
# p240521/function-ex5.html
매개변수가 있는 함수를 호출할 때 사용자가 입력한 인수의 정보를 알 수 있음

<script>
// 1. 함수 정의
function avg() {
var total = 0;
console.log('>>> avg() 실행');
console.log('arguments : ', arguments);
console.log('arguments 길이 : ', arguments.length);
for (let i=0; i<arguments.length; i++) {
console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
console.log('총합 : ', total);
}
// 2. 함수 호출
avg(2, 3, 5);
</script>
# 실행 결과
>>> avg() 실행
arguments : Arguments(3) [1, 2, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
arguments 길이 : 3
arguments[0] : 2
arguments[1] : 3
arguments[2] : 5
평균 구하기
- .toFixed(고정할 자리수)
<script>
function avg() {
// 평균 구하기
var total = 0;
for (let i=0; i<arguments.length; i++) {
// console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
var mean = (total / arguments.length).toFixed(2); // .toFixed(고정할 자리수)
return mean;
}
// 2. 함수 호출
var reslut = avg(2, 3, 5);
console.log('avg(2, 3, 5) 호출 결과 : ', reslut);
// console.log('[함수 밖] arguments : ', arguments) error !
</script>
# 실행 결과
avg(2, 3, 5) 호출 결과 : 3.33
★ 왜 error 일까 ?!
console.log('[함수 밖] arguments : ', arguments) error !
- 자바스크립트가 실행이 되면서 gloval 을 사용함
- 한 페이지 스크립트가 여러 개여도 gloval 영역은 하나만 생성
- 사진처럼 공용으로 공유 함
- 자바스크립트가 실행되기 전에 필요한 메모리를 미리 메모리 할당
- 자바스크립트는 property(요소) 로 관리
- script 가 있으면 먼저 스크립트 내에 있는 코드가 위에서 아래로 읽으면서 이름이 있는 것들은 미리 global 영역에 메모리에 올려둠

Parameter 속성
# p240521/function-ex6.html
<script>
function avg() {
// 평균 구하기
var total = 0;
for (let i=0; i<arguments.length; i++) {
// console.log(`arguments[${i}] : ${arguments[i]}`)
total += arguments[i];
}
var mean = (total / arguments.length).toFixed(2); // .toFixed(고정할 자리수)
return mean;
}
// 2. 함수 호출
var reslut = avg(2, 3, 5);
console.log('avg(2, 3, 5) 호출 결과 : ', reslut);
// console.log('[함수 밖] arguments : ', arguments) error !
</script>
함수 종류
# 함수 선언식 : 선언적 함수, 함수명 있음
# 함수 리터럴 : 익명 함수, 함수명 없음
# 함수 표현식 : 익명 함수에 변수로 저장, 함수명은 아니고, 이름처럼 사용
# 화살표 함수 : arrow function (나중에 배울것)
함수 선언식
# p240521/function-ex7.html
<script>
// [함수 선언식] 선언적 함수, 일반 함수
// : 함수 정의 전에 호출 가능
// : 함수 호출 시기 제한 없음
// : 함수명 있음
// 2-1. 함수 호출
hi('박보검');
// 1. 함수 정의
function hi(name) {
console.log(name + "님, 안녕하세요 !");
}
// 2-2. 함수 호출
hi('홍길동');
</script>
실행 순서




함수 표현식
# p240521/function-ex7.html
<script>
// [함수 표현식]
// : 익명 함수를 변수에 저장
// : 함수 정의 전에 호출 불가능
// : 함수명 없음(변수를 함수명처럼 씀)
// <내가 정리한 것>
// : function 자체가 변수에 저장이 되는데, 정확히는 주소가 저장된 것
// : 변수를 통해 이름이 생긴 익명 함수
// : 메모리에 저장은 됐지만, 이름이 없어서 두번은 못 씀 하지만 변수에 저장돼서 사용 가능
// 변수(주소) 써서 갔는데 매개변수가 있으니 저장이 됨
// => 이를 통해 함수 선언식과 함수 표현식의 차이점을 알 수 있음
// : 메모리 할당 시기 : 해당 라인이 실행될 때
// : 그럼 미리 올려둬서 좋은 거 아닌가 ? NO, 쓸데없는 메모리까지 차지하게 됨
// 2-1. 함수 호출
// hello('곰돌이'); // error ! hello is not a function
// 1. 함수 정의
var hello = function (name) {
console.log(name + '안녕 ~ !');
}
// 2-2. 함수 호출
hello('이미자'); // 위에 error 가 나면 인터프리터 언어인 자바스크립트라 실행이 안됨
var hey = hello; // hey 를 통해 익명 함수를 찾아갈 수 있음
hey('고양이');
</script>
실행 순서




즉시 실행 함수 : 1회용
# p240521/function-ex7.html
<script>
// [즉시 실행 함수] 1회용 (f(매개변수))(매개변수)
// 초기화 작업, 1번만 쓰고 말 때
// 이러한 코드는 위에 두어야함
(function (name) {
console.log(name + "님, 또 만나서 반가워요 ~ ");
})('멍멍이')
</script>
[함수 선언식과 표현식] 생성과 실행 순서
# p240521/function-ex8.html
<script>
/*
[생성 순서] 함수 선언식 -> 익명 함수
[실행 순서] 익명 함수 -> 함수 선언식
*/
// [함수 선언식] 선언적 함수, 일반 함수
function hi(name) {
console.log(name + ', 안녕 ~ [일반 함수]')
}
// [함수 표현식] 익명 함수를 변수에 저장
// var hi 가 먼저 할당되지만 코드는 위에서 아래로 읽기 때문에 놓침
// 보통 const 로 선언을 많이 함
var hi = function hi(nickname) {
console.log(nickname + ', 님, 안녕하세요 !')
}
// 함수 호출
console.log('>>> 함수 호출 전')
hi('홍길동');
console.log('>>> 함수 호출 후')
</script>
인수
# p240521/function-ex9.html
<script>
// 함수 정의
function hello() {
console.log('Hello ~~~~');
}
function hi() {
console.log('Hi !!!!!');
}
function execute(args) {
console.log('>>> 함수 실행 시작');
args();
console.log('>>> 함수 실행 종료');
}
// 함수 호출
// hello();
execute(hello); // 매개변수에 함수명을 입력, 함수 주소가 해당 함수를 찾아감
execute(hi);
</script>
# 실행 결과
>>> 함수 실행 시작
Hello ~~~~
>>> 함수 실행 종료
>>> 함수 실행 시작
Hi !!!!!
>>> 함수 실행 종료
중첩 함수
# p240521/function-ex10.html
함수 정의 내 함수 정의, 호출 방법 2가지
- 함수 내 함수 호출
- 함수 내에 return 값으로 함수 호출
<script>
// outer function(createHello), inner function(hello)
function createHello() {
console.log('>>> 함수 시작');
function hello(name) { //
console.log('... hello() 함수 시작');
console.log(name + '님, 안녕하세요 !')
console.log('... hello() 함수 종료');
}
// 호출 방법 1. 함수 내 함수 호출
// hello();
console.log('>>> 함수 종료');
// 호출 방법 2. 함수 내에 return 값으로 함수 호출
return hello;
</script>
실행 순서








# p240521/function-ex11.html
<script>
function outer() {
console.log('>>> outer() 실행 시작');
function inner() {
console.log('... inner() 실행 !');
}
inner();
console.log('>>> outer() 실행 종료');
}
console.log('... 프로그램 시작 ...')
outer();
console.log('... 프로그램 종료 ...')
</script>
실행 순서





# p240521/function-ex12.html
<script>
function loopHello() {
let count = 0;
let printHello = function() {
count++; // 5월 22일 수업때 자세히 이야기
console.log(`${count} : Hello`)
if (count == 10) {
clearInterval(s); // 중지
}
}
// 이미 만들어진 function
// 일정한 간격으로 특정한 작업을 실행하고자 할 때 씀, java 의 thread
// 비동기
// 저장된 변수에 인수로 넣어줌
var s = setInterval(printHello, 1000); // 얘가 누군지 모르니까 변수 만들기
}
loopHello();
</script>
# p240521/function-ex12 copy.html
- ex12 코드에서 수정된 파일이 ex12 copy 파일인데 보통 이렇게 많이 쓰임 !
<script>
// 함수 정의
function loopHello() {
let count = 0;
var s = setInterval(function () {
count++; // 5월 22일 수업때 자세히 이야기
console.log(`${count} : Hello`)
if (count == 10) {
clearInterval(s); // 중지
}
} , 1000)
}
// 함수 호출
loopHello();
</script>
화살표 함수
https://print-blue.tistory.com/182
프로그래밍할 때 function 문법을 사용하는 이유
여러가지 기능을 하는 코드를 한 단어로 묶고 싶을 때 (나중에 재사용할 때)입출력 기능을 만들 때
print-blue.tistory.com
- arrow function 을 사용하면 함수 본연의 입출력 기능을 아주 직관적으로 잘 표현이 됨 (쉽고 예쁘게 표현된다는 의미)
화살표 함수 쓰기 전
# p240521/function-ex13.html
<script>
// 화살표 함수 : arrow function (JAVA Lamvba)
// 기본적으로 익명 함수를 변환한 것, 변수 꼭 써야함
var sum = function(a, b) {
return a + b;
}
var result = sum(4, 6);
console.log('result >> ', result);
</script>
화살표 함수 기능 구현
- 함수에 명령어이 하나만 있고, 명령문이 값을 반환하는 경우 {} 와 return 키워드를 제거할 수 있음
- {} 는 명령문이 하나만 있는 경우에만 작동
<script>
// 1) body 의 {} 생략, return 생략
// 매개변수와 바디 사이에 => 화살표 모양 넣기
var sum = (a, b) => a + b;
var result = sum(4, 6);
console.log('result >> ', result);
</script>
<script>
// 2) body 의 {} 명시
// : 리턴하려면, 무조건 return 키워드 명시
// {} 가 들어오는 순간 자동으로 return 이 안됨
// => 썼다는 자체가 익명 함수
var sum = (a, b) => {
return a + b;
}
var result = sum(4, 6);
console.log('result >> ', result);
</script>
화살표 함수의 정의 형태
# p240522/arrow-function-ex02.html
[화살표 함수의 정의 형태]
1. 매개변수 1개, 리턴값 있음
: 매개변수가 1개일 때, () 생략 가능
: 명령어가 1개일 경우, {} 생략 가능
2. 매개변수 없고, 리턴값 있음
: () 생략 불가능
: 명령어가 1개일 경우, {} 생략 가능
3. 매개변수 1개, 리턴값 있음, 명령어 여러 개
: () 생략 가능
: 명령어가 여러 개일 경우, {} 생략 불가능
4. 매개변수 2개, 리턴값 없음, 명령어 여러 개
: () 생략 불가능
: 명령어가 여러 개일 경우, {} 생략 불가능
5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
: () 생략 불가능
: 명령어가 여러 개일 경우, {} 생략 불가능
1. 매개변수 1개, 리턴값 있음
<script>
// 1. 매개변수 1개, 리턴값 있음
var one = args => args + 1;
var result = one(100);
console.log('one(100) 호출 결과 >>', result);
console.log('one() 호출 결과 >>', one()); // NaN
</script>
# 실행 결과
one(100) 호출 결과 >> 101
one() 호출 결과 >> NaN
2. 매개변수 없고, 리턴값 있음
<script>
// 2. 매개변수 없고, 리턴값 있음
// const two = () => {'문자열입니다.'}; // undefined
const two = () => '문자열입니다.';
console.log('two() 호출 결과 >>', two());
console.log('two(100) 호출 결과 >>', two(100));
</script>
# 실행 결과
two() 호출 결과 >> 문자열입니다.
two(100) 호출 결과 >> 문자열입니다
3. 매개변수 1개, 리턴값 있음
<script>
// 3. 매개변수 1개, 리턴값 있음, 명령어 여러 개
const three = args => {
let num = args + 1;
return `1 증가한 값 : ${num}`;
}
console.log('three(5) 호출 결과 >>', three(5));
</script>
# 실행 결과
three(5) 호출 결과 >> 1 증가한 값 : 6
4. 매개변수 2개, 리턴값 없음, 명령어 여러 개
<script>
const four = (a, b) => {
let result = a + b;
console.log(`매개변수 a : ${a}, 매개변수 b : ${b}`);
console.log(result);
}
four(1, 3);
console.log('four(2, 4) 호출 결과 >>', four(2, 4)); // return 값이 없어 undefined
four(); // NaN
</script>
# 실행 결과
매개변수 a : 1, 매개변수 b : 3
4
매개변수 a : 2, 매개변수 b : 4
6
four(2, 4) 호출 결과 >> undefined
매개변수 a : undefined, 매개변수 b : undefined
NaN
5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
<script>
// 5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
// 기본값 : 매개변수가 있을 경우 인수에 저장되고, 없으면 인수에 기본값이 들어옴
// 기본값 설정 : (a=0, b=0) or (a='', b='')
const five = (a=0, b=0) => {
let result = a + b;
console.log('덧셈 결과 : ', result);
}
five('뭉게', '구름');
five(); // 기본값 설정 안했을 때 : NaN
</script>
# 실행 결과
덧셈 결과 : 뭉게구름
덧셈 결과 : 0
호이스팅(hoisting)
# p240522/hoisting-ex01.html
[호이스팅]
: 인터프리터가 변수(와 함수 등)의 메모리 공간을 미리 할당
: 호이스팅 시 변수(외 함수 등)는 undefined 초기화
: 선언과 초기화를 분리 (변수 기준)
# p240522/hoisting.html
[scope]
- global scope (전역 스코프)
: <script> 내 선언된 변수
: 어디서든지 접근 가능
- local scope (지역 스코프)
: {} 내 선언된 변수
: 해당 영역 내에서만 접근 가능
: function level scope - var
: block level scope - let, const
# p240522/hoisting-ex01.html
<script>
// script 자체가 global 영역
// 할당되어야 하는 것들을 미리 할당하는데, 라인 처리가 되지 않아서 초기값을 설정되지 못함
// 그래서 값은 undefined 로 들어옴
// [global scope(글로벌 영역)]
console.log('변수 선언 전 접근');
var a_var;
console.log('a_var 선언 후');
console.log('a_var :', a_var);
var a_hi = '안뇽'; // 변수 선언 후 초기화
console.log('a_hi :', a_hi);
</script>





var 변수와 let 변수 선언
# p240522/hoisting-ex02.html
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
var a_var;
let a_let;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
</script>
실행 순서


그럼 다시
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
</script>
실행 순서


var 변수와 let 변수 선언, const 변수 선언
# p240522/hoisting-ex02.html
값 설정은 라인 처리가 될 때 초기화가 됨
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
// console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
// 상수(const)
// : cf) 리터럴 Literal
// : 선언과 동시에 초기화
const a_const = 20;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
</script>
실행 순서


값 변경
# p240522/hoisting-ex02.html
<script>
console.log('[변수 선언 전 접근]');
console.log('a_var : ', a_var);
// console.log('a_let : ', a_let);
var a_var = 5;
let a_let = 10;
// 상수(const)
// : cf) 리터럴 Literal
// : 선언과 동시에 초기화
const a_const = 20;
console.log('[변수 선언 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
// 값 변경
var a_var = 100;
// let a_let = 200; // error ! 재선언
a_let = 200; // 영역이 다르기 때문에 가능
// const a_const = 300; // error ! 재선언
a_const = 300;
console.log('[값 변경 후 접근]');
console.log('a_var : ', a_var);
console.log('a_let : ', a_let);
console.log('a_const : ', a_const);
</script>
실행 순서


scope(스코프)

# p240522/scope-ex01.html
- 보통 함수 선언은 head 태그 내에 선언을 함
<head>
<title>[scope]</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
console.log('=== <head> 내 script ===');
var a_head_var = 100;
let a_head_let = 200;
const a_head_const = 300;
console.log('a_head_var : ', a_head_var);
console.log('a_head_let : ', a_head_let);
console.log('a_head_const : ', a_head_const);
// 함수 선언식
function a_sum(num1, num2) {
console.log('덧셈 결과 : ', num1 + num2);
}
</script>
</head>
<body>
<h1>[scope]</h1>
<script>
console.log('=== <body> 내 script ===')
console.log('a_head_var : ', a_head_var);
console.log('a_head_let : ', a_head_let);
console.log('a_head_const : ', a_head_const);
// 함수 호출
a_sum('뭉게', '구름');
var a_body_var = 5;
console.log('... 종료')
</script>
</body>
실행 순서






만약 body 에서 선언한 a_body_var 를 head 에서 콘솔 로그를 찍으면 될까 ?
안 된 다 !!! 아직 body 에 있는 script 태그를 읽지 않아서 가져 올 수가 없다 !!
# p240522/scope-ex02.html
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one); // 값이 undefined
var a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>
실행 순서






코드 변경 1. 조건문 추가
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one); // 값이 undefined
var a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
// 조건문
if (a_global == 1) {
// [지역변수]
var a_local_two = 100;
console.log('[지역변수] if문 내 a_local_two >> ', a_local_two);
}
console.log('[지역변수] if문 밖 a_local_two >> ', a_local_two);
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>

코드 변경 2. 변수 변경 var -> let
<script>
// [전역변수]
var a_global = 1;
// 함수 정의
function a_scope_test() {
console.log('[전역변수] a_global >> ', a_global);
// [지역변수]
// console.log('[지역변수] 선언 전 : a_local_one >> ', a_local_one);
// (var)값이 undefined / (let) error 값이 없음
// var a_local_one = 10;
let a_local_one = 10;
console.log('[지역변수] 선언 후 : a_local_one >> ', a_local_one);
// console.log('[지역변수] a_local_one >> ', this.a_local_one);
// 조건문
if (a_global == 1) {
// [지역변수]
let a_local_two = 100;
console.log('[지역변수] if문 내 a_local_two >> ', a_local_two);
}
// console.log('[지역변수] if문 밖 a_local_two >> ', a_local_two);
// (var)값이 undefined / (let) error 값이 없음
}
// 함수 호출
a_scope_test();
// console.log('[지역변수] a_scope_test() 밖에서 a_local_one >> ', a_local_one); // 메모리 사라져서 사용(접근)할 수 없음 !
console.log('=== script 종료 ===');
</script>
실행 순서




var
# p240522/scope-ex03.html
<script>
// 전역변수
var a_one = 1;
let a_two = 2;
const a_three = 3;
for (var a_i=0; a_i<3; a_i++) {
console.log('a_i >> ', a_i);
}
if (a_one == 1) {
var a_four = 4;
console.log('a_four >> ', a_four);
}
function sum() {
var a_five = 5;
console.log('a_five >> ', a_five);
}
console.log('a_one : ', a_one);
console.log('a_two : ', a_two);
console.log('a_three : ', a_three);
</script>

var -> let 변경
# p240522/scope-ex03.html
<script>
// 전역변수
var a_one = 1;
let a_two = 2;
const a_three = 3;
for (let a_i=0; a_i<3; a_i++) {
console.log('a_i >> ', a_i);
}
if (a_one == 1) {
let a_four = 4;
console.log('a_four >> ', a_four);
}
function sum() {
var a_five = 5;
console.log('a_five >> ', a_five);
}
console.log('a_one : ', a_one);
console.log('a_two : ', a_two);
console.log('a_three : ', a_three);
</script>



렉시컬 스코프(lexical scope)
[Lexical Scope]
: Lexical - 어휘의, 사전의;
: 함수를 어디에 정의하였는지에 따라 상위 스코프를 결정하는 것
# p240522/lexical-scope-ex01.html
<script>
var a = 1;
var b = 2;
var c = 3;
function outer() {
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== outer() 호출 전 ===');
outer();
console.log('=== outer() 호출 후 ===');
</script>
# 실행 결과
=== outer() 호출 전 ===
[outer 내] a : 1, b : 20, c : 30
=== outer() 호출 후 ===



function 안에 또 function
# p240522/lexical-scope-ex01.html
<script>
var a = 1;
var b = 2;
var c = 3;
function outer() {
var b = 20;
var c = 30;
function inner() {
var c = 300;
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== inner() 호출 전 ===');
inner();
console.log('=== inner() 호출 후 ===');
console.log(`[outer 내] a : ${a}, b : ${b}, c : ${c}`);
}
console.log('=== outer() 호출 전 ===');
outer();
console.log('=== outer() 호출 후 ===');
</script>




# p240522/lexical-scope-ex02.html
<script>
var a_num = 5;
function a_you() {
var a_num = 500;
console.log('== [a_you() 함수 내] a_need() 호출 ==', a_num);
a_need();
}
function a_need() {
console.log('a_need() 함수 내 변수 a_num 접근', a_num)
}
console.log('== a_you() 호출 ==');
a_you();
console.log('== a_need() 호출 ==');
a_need();
console.log('... script 영역 끝 ...');
</script>
실행 순서









[함수] 메모리 할당 시기
#p240522/arrow-function-ex01.html
<script>
console.log('*** script 영역 시작 ***');
// 함수 선언식 : 이름이 있는 함수
function a_one() {
console.log('a_one() 실행');
}
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
console.log('*** script 영역 종료 ***');
</script>


<script>
console.log('*** script 영역 시작 ***');
// 함수 호출 // 추가 !
a_one();
// a_two(); 아직 할당되어 있지 않아서 호출이 안됨
// 함수 선언식 : 이름이 있는 함수
function a_one() {
console.log('a_one() 실행');
}
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
console.log('*** script 영역 종료 ***');
</script>
화살표 함수로 변경하기
// 함수 표현식 : 익명 함수를 변수에 저장
var a_two = function() {
console.log('a_two() 실행');
}
// 화살표 함수
var a_two = () => console.log('a_two() 실행');



callback 함수
[콜백 함수]
가장 큰 이유 : 비동기 처리 때문
# 매개변수가 함수명 받음
=> 함수 내에서 함수 호출
자바스크립트에서 변수에 함수를 받는 것처럼 생각하면 됨 (JS 에서 흔한 일)
# 함수 내부 처리 결과값을 외부 함수로 내보낼 때
=> return 과 비슷
# 주로 비동기 처리
[문법]
funtion 함수명(callback) { // callback 인수(인자) 라 불림
callback();
}
p240527/callback-ex01.html
일반적인 함수
<script>
// [함수 선언식] 리턴 사용
function add(num1, num2) {
return num1 + num2;
}
// [함수 호출]
var result = add(2, 5);
console.log('result >> ', result);
</script>
callback 함수
제어권이 넘어갔다는 말도 씀
시간 순서대로 처리된 것이 동기 처리
<script>
// [함수 선언식]
console.log('--- add 함수 시작 ---');
function add(num1, num2, callback) { // callback : 매개변수
var result = num1 + num2;
callback(result);
console.log('--- add 함수 종료 ---');
}
function addResult(value) {
console.log('... addResult 함수 시작 ...');
console.log('덧셈 결과 >> ', value);
console.log('... addResult 함수 종료 ...');
}
function addResultTwo(value) {
console.log('___ addResultTwo 함수 시작 ___');
console.log('합 : ', value);
console.log('___ addResultTwo 함수 종료 ___');
}
// [함수 호출]
// add(1, 4); // error ! callback is not a function, 값 설정 undefined 됨
add(1, 4, addResult);
add(2, 5, addResultTwo);
</script>
p240527/callback-ex02.html
함수 내에서 선언된 지역 변수가 보통 return 을 해야 값을 넘길 수 있는데
callback 함수를 통해 return 효과를 나타냄
함수명을 인수로 설정 - 인수로 설정될 함수 미리 정의
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 1) 함수명을 인수로 설정
// 인수로 설정될 함수 미리 정의
// (1-1) 함수 선언식
function addResult(value) {
console.log('a-1. 덧셈 결과 >> ', value);
}
// (1-1) 함수 표현식
const addResult = function(value) {
console.log('a-2. 덧셈 결과 >> ', value);
}
add(1, 3, addResult);
</script>
# 실행 결과
a-1. 덧셈 결과 >> 4
매개변수에 저장된 함수 >>
ƒ addResult(value) {
console.log('a-1. 덧셈 결과 >> ', value);
}
a-2. 덧셈 결과 >> 4
매개변수에 저장된 함수 >>
ƒ (value) {
console.log('a-2. 덧셈 결과 >> ', value);
}

익명 함수를 인수로 설정 (많이 사용)
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 2) 익명 함수를 인수로 설정 (많이 사용)
// [문법] add(매개변수1, 매개변수2, function() {})
add(3, 7, function(value) {
console.log('b. 덧셈 결과 >> ', value);
})
add(1, 3, addResult);
</script>
# 실행 결과
b. 덧셈 결과 >> 10
매개변수에 저장된 함수 >>
ƒ (value) {
console.log('b. 덧셈 결과 >> ', value);
}
화살표 함수를 인수로 설정 (많이 사용)
<script>
// [함수 선언식]
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('매개변수에 저장된 함수 >> ');
console.log(callback);
}
// [함수 호출]
// (형태 3-1) 화살표 함수를 인수로 설정(많이 사용)
add(7, 9, (value) => {
console.log('c-1. 덧셈 결과 >> ', value)
});
// (형태 3-2) 화살표 함수를 인수로 설정(많이 사용)
add(6, 8, value => console.log('c-2. 덧셈 결과 >> ', value));
</script>
# 실행 결과
c-1. 덧셈 결과 >> 16
매개변수에 저장된 함수 >>
(value) => {
console.log('c-1. 덧셈 결과 >> ', value)
}
c-2. 덧셈 결과 >> 14
매개변수에 저장된 함수 >>
value => console.log('c-2. 덧셈 결과 >> ', value)
p240527/callback-ex03.html
<script>
function add(num1, num2, callback) {
var result = num1 + num2;
callback(result);
console.log('--- add() 실행 종료 ---');
}
add(1, 3, value => {
console.log('덧셈 결과 : ', value);
console.log('== 화살표 함수 실행 종료 ==')
});
console.log('script 영역 끝 !');
</script>
실행 순서





동기/비동기
<네트워크 기준>
[동기] - 시간을 맞추는 것
클라이언트가 서버한테 무언가를 요청할 때,
서버가 응답할 때까지 클라이언트는 작업을 하지 않는다.
[비동기]
클라이언트가 서버한테 무언가를 요청할 때,
서버가 응답할 때까지 클라이언트는 다음 작업을 먼저 한다.
p240527/callback-ex04.html
동기
<script>
// <자바스크립트 기준>
// [동기] - 위에서 아래로 순차적으로 진행
console.log('alert() 실행 전 출력됩니다.');
alert('ㅎㅇ');
console.log('alert() 실행 후 출력됩니다.');
</script>


비동기
<script>
// [비동기]
var count = 1;
console.log('>>> setInterval() 실행 전 >>>');
// setInterval()
// 특정 기능(코드)을 일정한 시간 간격으로 반복 실행
// setInterval(콜백함수, 시간);
setInterval(() => {
console.log('... count : ', count);
count++;
}, 1000);
console.log('>>> setInterval() 실행 후 >>>');
</script>
실행 순서




배열 함수
find
[find]
조건에 맞는 요소(속성) 하나만 찾음
즉, 조건에 맞는 요소(속성)를 찾으면 탐색 중지
find 에서는 for문 기능이 있음, 순회를 돔
찾고자 하는 조건을 넣고, return 을 해줘야 원하는 값을 받을 수 있음
조건에 맞는 요소 1개만 retunrn
조건에 맞는 요소(속성)가 있으면, 해당 요소 리턴
조건에 맞는 요소(속성)가 없으면, undefined 리턴
[문법] 배열.find(function(value[, index[, array]])) [] 생략 가능하다는 뜻
value = 요소 / index = 요소의 인덱스 / array = 배열의 주소
p240527/array-ex01.html
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
// 길이가 2개인 요소 찾기
// 1. 매개변수 value 만 쓸 때, value 는 생략 불가능
const find_result_one = arr.find(value => value.length == 2);
console.log('find_result_one : ', find_result_one);
// 2. 매개변수 다 사용할 때
const find_result_two = arr.find((value, index, array) => {
console.log('value : ', value);
console.log('index : ', index);
console.log('array : ', array);
return value.length == 2; // true 가 되는 순간 return
})
console.log('find_result_two : ', find_result_two);
</script>
# 실행 결과
find_result_one : 하나
value : 하나
index : 0
array : (5) ['하나', '둘', '셋', '넷', '다섯']
array-ex01.html:39 find_result_two : 하나
filter
[filter]
조건에 맞는 여러 요소 모두 찾음
조건에 맞는 여러 요소를 모두 찾아 배열로 리턴
[문법] 배열.filter(function(value[, index[, array]])) [] 생략 가능하다는 뜻
p240527/array-ex02.html
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const filter_result = arr.filter(value => value.length == 3); // 빈문자열 리턴
console.log('filter_result >> ', filter_result);
const filter_result = arr.filter(value => value.length == 2);
console.log('filter_result >> ', filter_result);
const filter_result_two = arr.filter((value, index, array) => {
console.log('value : ', value);
console.log('index : ', index);
console.log('array : ', array);
return value.length == 2;
});
console.log('filter_result_two >> ', filter_result_two);
</script>

map, forEach
p240527/array-ex03.html
map
[map]
배열 요소를 순회하면서, 특정 작업(기능) 수행(실행)
배열 리턴
복사본을 리턴, 원래 데이터는 영향 x
실제 원하는 기능은 인수로 넣어주는 형태, 외부에서 넣어주는 게 콜백 함수
[문법] 배열.map(function(value[, index[, array]]))
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const map_result = arr.map(value => value + '! 좋아요!');
// 확인할 때 데이터 타입을 구분하기 위해서 문자열과 데이터를 따로 출력함
console.log('map_result >> ');
console.log(map_result);
console.log('arr >> ');
console.log(arr); // 원본은 그대로 있는 걸 확인하면서 알 수 있는 점은 map 은 복사본
</script>
# 실행 결과
map_result >>
(5) ['하나! 좋아요!', '둘! 좋아요!', '셋! 좋아요!', '넷! 좋아요!', '다섯! 좋아요!']
arr >>
(5) ['하나', '둘', '셋', '넷', '다섯']
forEach
// [forEach]
배열 요소를 순회하면서, 특정 작업(기능) 수행(실행)
리턴 없음 (undefined)
[문법] 배열.forEach(function(value[, index[, array]]))
<script>
var arr = ['하나', '둘', '셋', '넷', '다섯'];
const forEach_result = arr.forEach(value => console.log(value + '! 좋아요!'));
console.log('forEach_result >> ');
console.log('arr >> ');
console.log(arr); // 원본은 그대로 있는 걸 확인하면서 알 수 있는 점은 forEach 은 복사본
</script>
# 실행 결과
하나! 좋아요!
둘! 좋아요!
셋! 좋아요!
넷! 좋아요!
다섯! 좋아요!
forEach_result >>
arr >>
(5) ['하나', '둘', '셋', '넷', '다섯']
배열 함수 예제
p240527/array-ex04.html
배열 even 의 요소를 1 증가 후, (복사본) 출력
<script>
const even = [2, 4, 6, 8, 10];
// [forEach]
// 1) 익명 함수
even.forEach(function (args) {
console.log(args + 1);
});
// 2) 화살표 함수
even.forEach(args => console.log(args + 1));
console.log('\n');
// [map]
console.log('map_result >> ');
console.log(even.map(args => args + 1));
</script>
# 실행 결과
[forEach]
1) 익명 함수
3
5
7
9
2) 화살표 함수
3
5
7
9
[map]
map_result >>
(5) [3, 5, 7, 9, 11]
배열 even 의 요소를 1 증가
<script>
// 배열 even 의 요소를 변경
even.forEach((value, index, array) => {
array[index] = value + 1;
});
console.log('even >>');
console.log(even);
</script>
# 실행 결과
even >>
(5) [3, 5, 7, 9, 11]
일반 for 문과 forEach() 함수 비교
p240527/array-ex05.html
<script>
// 배열
const student = ['홍길동', '박보검', '이미자'];
// 함수 표현식
const info = function(value, index) {
console.log(`value : ${value}, index : ${index}`);
};
</script>
일반 for문
<script>
console.log('<< for문 >>');
for(let index=0; index<student.length; index++) {
info(student[index], index); // info() 함수 호출
}
</script>
# 실행 결과
forEach()함수
<script>
console.log('<< forEach() >>');
// student.forEach(info); // info() 함수 호출
const forEach_result = student.forEach(info);
console.log(forEach_result);
// undefined
// : return 이 없으면 undefined 로 저장
</script>
# 실행 결과
map() 함수
<script>
// cf) map() 함수
console.log('<< map() >>');
// student.map(info); // info() 함수 호출
const map_result = student.map(info);
console.log(map_result);
// (3) [undefined, undefined, undefined]
// : callback 함수 사용할 때 return 사용
// : info() 에서 return 을 해주지 않아서
// 만약 배열 형태로 값을 하고 싶을 때 info()의 <// 추가> 부분 확인
</script>
# 실행 결과

closure (클로저)
[클로저] closure
# 함수 내부에서 만든 지역변수가 사라지지 않고 계속 유지하는 상태
# 클로저 : 함수와 그 함수가 정의 되었을 때의 렉시컬 환경의 조합
# 클로저는 자신이 생성될 때 환경(Lexical environment)을 기억하는 함수
p240527/closure-ex01.html
<script>
function outer() {
var count = 1;
function inner() {
count++;
console.log('count >> ', count);
}
return inner;
}
var result = outer();
result();
</script>
실행 순서






<script>
function outer() {
var count = 1;
function inner() {
count++;
console.log('count >> ', count);
}
console.log('[outer 지역변수 count] >> ', count);
return inner;
}
// inner() 에서 사용한 count(복사본)
// inner 주소를 갖고 실행, inner 의 local 이 된 것 (outer() 아님)
// inner 에 저장된 count 가 저장되어 있는 값을 가지고 옴
var result = outer();
result();
result();
result();
// outer() 에서 사용한 count(원본)
// outer 가 실행되면, count 가 지역 변수라 당연히 1이 나옴
outer();
result();
console.log('... script 영역 종료 ...')
</script>
# 실행 결과
[outer 지역변수 count] >> 1
count >> 2
count >> 3
count >> 4
[outer 지역변수 count] >> 1
count >> 5
... script 영역 종료 ...
실행 순서






p240527/closure-ex02.html
<script>
// 클로저 형태 o ================================================
// [함수 선언식]
function creatCount() {
console.log('=== creatCount() 함수 시작 ===');
var count = 0; // 상위 스코프의 지역변수, 별도로 따로 관리되는 형태
console.log('지역변수 count >> ', count);
console.log('=== creatCount() 함수 종료 ===');
// 클로저가 사용하는 자유 변수
// inner() 에서 쓰는 상위 스코프의 지역변수만 ! 기억하고 다른 건 기억x
// 근데 이 코드에서는 계속 호출이 되는데 기억을 하고 있어야 해서 이러한 개념을 클로저
// 폐쇄적임, 닫혀있음
// 해당 지역변수는 다른 곳에서 사용 x
// var count = 0;
// 함수 내에 지역변수를 선언안하는 이유
// : 매번 실행될 때마다 count = 0 이 먼저 실행되기 때문에 값이 초기화됨
// return function () {
// count++;
// return count;
// }
return () => ++count;
// 후증가를 하면 결과값이 다름
// 함수 내에 addCount() 호출하지 않아 이름이 의미가 없음
// return addCount;
}
// 문제가 생기는 점 : 함수가 따로 실행될 때
var returnAddCount = creatCount();
for(let i=0; i<3; i++) {
console.log(i+1, "회 : returnAddCount() 호출 >> ", returnAddCount());
}
// returnAddCount();
// returnAddCount();
// returnAddCount();
console.log('... script 영역 종료 ...')
</script>
# 실행 결과
=== creatCount() 함수 시작 ===
지역변수 count >> 0
=== creatCount() 함수 종료 ===
1 '회 : returnAddCount() 호출 >> ' 1 '
2 '회 : returnAddCount() 호출 >> ' 2 '
3 '회 : returnAddCount() 호출 >> ' 3 '
... script 영역 종료 ...
https://jhyonhyon.tistory.com/13
[Javascript] 클로저(Closure)란?
클로저 정의 클로저(Closure)는 자유변수에 접근할 수 있는 내부함수 또는 그 환경을 포함하는 코드를 지칭한다. MDN(Mozilla Developer Network) [모질라 재단및 다른 IT기업들이 사용하는 웹 개발을 위한
jhyonhyon.tistory.com
DOM (document)
특정 엘리먼트 찾기 1
1. 단일 element 추출(반환)
- 여러 개인 경우 첫 번째만 추출
1-1) document.getElementById('아이디')
1-2) document.querySelector('선택자')
아이디 : #아이디
클래스 : .클래스
태그 : 태그
2. 복수 element 추출(반환)
2-1) document.getElementsByClassName('클래스명')
2-2) document.getElementsByTagName('태그')
2-3) document.querySelectorAll('선택자')
document.querySelectorAll('선택자1, 선택자2') -> 선택자1 or 선택자2
p240528/dom-ex01.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 특정 엘리먼트 찾아가기</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>DOM</h1>
<div id="txt" class="c_txt">Hello</div>
<div id="greeting" class="c_txt">안녕</div>
<hr>
<script src="js/dom-ex01.js"></script>
</body>
</html>
p240528/js/dom-ex01.js
// 1. 단일 element 추출(반환)
// JS 프로그래밍 언어
// 복사본을 저장한 게 아니라, 속성을 담아둔 것
// script 태그를 body 닫힌 태그 바로 위에 둠
// 만약 head 태그 쪽에 두면 error 가 발생
// -> 해당 element 에 접근이 안됨
// -> html 렌더링하면서 js 가 먼저 실행되고, 아직 body 태그를 읽지 못햇음
// head 에 오는 script 는 funtion 정의, 전역변수, 초기화 작업 등등이 있음
// Hello 에서 변경된 테스트로 변경된 이유 : 주기적으로 접근
const id_txt = document.getElementById('txt');
const id_greeting = document.querySelector('#greeting');
// 2. 복수 element 추출(반환)
const class_c_txt = document.getElementsByClassName('c_txt');
const div = document.getElementsByTagName('div');
// query 를 쓰면 타입이 HTMLCollection 가 아닌 NodeList 로 됨
const seletorAll = document.querySelectorAll('.c_txt');
const seletorAll2 = document.querySelectorAll('h1, .c_txt'); // 중복이 된다면 중복 제거
// 출력
console.log('id_txt >>', id_txt);
console.log('id_txt type >>', typeof id_txt);
id_txt.innerText = '변경된 텍스트 !';
console.log('id_txt.innerText >>', id_txt.innerText);
console.log('\n');
console.log('id_greeting >> ', id_greeting);
console.log('id_greeting type >>', typeof id_greeting);
console.log('\n');
console.log('class_c_txt', class_c_txt);
console.log('class_c_txt type >>', typeof class_c_txt);
console.log('class_c_txt[1].innerText >>', class_c_txt[1].innerText);
console.log('class_c_txt[1]["innerText"]) >>', class_c_txt[1]['innerText']);
console.log('class_c_txt.greeting.innerText >>', class_c_txt.greeting.innerText);
console.log('class_c_txt.greeting["innerText"] >>', class_c_txt.greeting['innerText']);
console.log('\n');
// HTMLCollection
console.log('div >> ', div);
console.log('div type >>', typeof div);
console.log('\n');
// NodeList
console.log('seletorAll >> ', seletorAll);
console.log('seletorAll type >>', typeof seletorAll);
console.log('seletorAll[1].innerText >> ', seletorAll[1].innerText);
// console.log('seletorAll[1].innerText >> ', seletorAll.greeting.innerText); // id 접근이 안됨
console.log('\n');
console.log('seletorAll2 >> ', seletorAll2);
console.log('seletorAll2 type >>', typeof seletorAll2);
// 아이디라서 쓸 수 있음
// console.log('txt.innerText >>', txt.innerText);
// txt.innerText = '뭐꼬 ㅠㅠ';
특정 엘리먼트 찾기 2
p240528/dom-ex02.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 특정 엘리먼트 찾아가기 2</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
p.paragraph {
text-align: center;
}
</style>
</head>
<body>
<h1 id="title">제목</h1>
<div id="append"></div>
<p class="paragraph">첫번째 단락</p>
<p class="paragraph">두번째 단락</p>
<p class="paragraph">세번째 단락</p>
<hr>
<script src="js/dom-ex02.js"></script>
</body>
</html>
p240528/js/dom-ex02.js
- 자바스크립트를 통해 html 추가한 것은 동적 추가라 불림
- 자바스크립트를 통해 스타일 적용하는 것은 inline 스타일로 들어옴(우선 순위 높음)
// 1. id 를 통해서 title 을 '제목' -> '변경된 제목'
title.innerText = '변경된 제목';
// 2. id 를 통해 append 에 content 로 h3 태그로 '추가된 제목' 넣어주기
// 자바스크립트를 통해 html 추가한 것은 동적 추가 라 불림
append.innerHTML = '<h3>추가된 제목</h3><div>추가 !</div>'
// 3-1. 첫 번째 단락에 접근
const selector = document.querySelector('.paragraph');
// console.log('첫 번째 단락 접근 >> ');
// console.log(selector);
// 3-2. 첫 번째 단락 innerText 변경 후폰트 색상 변경
selector.innerText = '첫 번째 단락만 변경';
selector.style.color = 'blue' // 자바스크립트를 통해 스타일 적용하는 것은 inline 스타일로 들어옴 (우선 순위가 높음)
// 3-3. [문제] 모든 단락의 텍스트를 가로 가운데 정렬하시오.
const paragraph = document.querySelectorAll('p.paragraph');
// [방법 1] for of
// cf) for in : key 추출
// for(let para of paragraph) {
// para.style.textAlign = 'center';
// }
// [방법 2] 함수 정의
// 함수 표현식
// const setTextAlign = function(args) {
// args.style.textAlign = 'center';
// }
// for(let para of paragraph) {
// setTextAlign(para);
// }
// 화살표 함수
// const setTextAlign = args => args.style.textAlign = 'center';
// for(let para of paragraph) {
// setTextAlign(para);
// }
// [방법 3] 배열 함수 forEach
// paragraph.forEach(); // TypeError : ndefined is not a function at NodeList.forEach
const arr_paragraph = Array.from(paragraph); // NodeList -> Array
// console.log('arr_paragraph >> ');
// console.log(arr_paragraph);
console.log('arr_paragraph type >> ', typeof arr_paragraph);
arr_paragraph.forEach(element => element.style.textAlign = 'center');


이벤트
p240528/dom-ex03.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 이벤트</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>
<h1 id="greeting">Hello ~~ (。・ω・。)</h1>
<!-- 기본 type값 : submit(이동) -->
<!--
[방법 1] 예전에 많이 사용,
문제점 : 유지보수 쉽지 않음(함수명 바꾸면 다 바꿔야함)
textChange() 은 자바스크립이기 때문에 (;) 생략 가능하지만,
직관성을 위해 붙이는 경우 있음
-->
<button type="button" onclick="textChange();">텍스트 변경</button>
<button type="button" onclick="textBefore();">텍스트 복구</button>
<hr>
<button type="button" id="one">[jQuery] 텍스트 변경</button>
<button type="button" id="two">[jQuery] 텍스트 복구</button>
<script src="js/dom-ex03.js"></script>
</body>
</html>
p240528/js/dom-ex03.js
const element = document.getElementById('greeting');
const greetingInitialText = element.innerText;
// 함수 선언식
function textChange() {
element.innerText = '오늘도 화이팅 ㅋ (。・∀・)ノ゙';
element.style.background = '#ff0';
}
function textBefore() {
element.innerText = greetingInitialText;
element.style.background = 'initial'; // 초기화
}
// [방법 2]
// [jQuery]
// $(선택자); 달러 함수
// const greeting = $('#greeting');
// console.log(greeting);
$('#one').click(() => {
$('#greeting').html('즐거운 오후 ㅋ(~ㅅ~)~zZ');
});
$('#two').click(() => {
$('#greeting').html(greetingInitialText);
});





이벤트 핸들러 등록과 삭제
[이벤트 리스너]
: 이벤트가 발생했을 때, 그 처리를 담당하는 함수
: 이벤트 핸들러(event handler) - 이벤트 감지 후, 실행하는 함수
<문법>
element.addEventListener('이벤트', 이벤트핸들러);
=> 이벤트 핸들러를 이벤트 리스너(addEventListener)에 등록한다 라고 말함
p240528/dom-ex04.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>DOM - 이벤트 2</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>
<h1 id="greeting">Hello</h1>
<button type="button" class="emoji">이모지 출력 💙💌</button>
<button type="button" class="remove">이모지 해제 💙📧</button>
<script src="js/dom-ex04.js"></script>
</body>
</html>
p240528/js/dom-ex04.js
// [방법 3]
const emoji = document.querySelector('.emoji');
const remove = document.querySelector('.remove');
const h1 = document.querySelector('h1');
// [이벤트 리스너]
// : 이벤트가 발생했을 때, 그 처리를 담당하는 함수
// : 이벤트 핸들러(event handler) - 이벤트 감지 후, 실행하는 함수
// <문법>
// element.addEventListener('이벤트', 이벤트핸들러);
// => 이벤트 핸들러를 이벤트 리스너(addEventListener)에 등록한다 라고 말함
// [이벤트 핸들러]
// [함수 선언식]
function emojiHandler(event) {
console.log(event);
console.log('🎀');
}
// 이벤트 핸들러 해제
// [화살표 함수]
const removeHandler = () => {
console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
emoji.removeEventListener('click', emojiHandler); // 이벤트 핸들러 해제
}
// 이벤트 핸들러를 이벤트 리스너에 등록
// 콜백함수로 넣을 것
// [공부] 화살표 함수로 바꾸기
emoji.addEventListener('click', emojiHandler);
remove.addEventListener('click', removeHandler);
// [공부] 함수 표현식으로 바꾸기
h1.addEventListener('mouseover', () => console.log('마우스 쥐나가요 ~ ㅋ'));
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});
p240528/js/dom-ex04-re.js
// [방법 3]
const emoji = document.querySelector('.emoji');
const remove = document.querySelector('.remove');
const h1 = document.querySelector('h1');
// [함수 표현식으로 정의] ===========================================
// [이벤트 핸들러]
// const emojiHandler = function(event) {
// console.log(event);
// console.log('🎀');
// }
// const removeHandler = function() {
// console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
// emoji.removeEventListener('click', emojiHandler); // 이벤트 핸들러 해제
// }
// const mouseoverChange = function() {
// console.log('마우스 쥐나가요 ~ ㅋ');
// }
// const clickChange = function() {
// h1.innerText = '쪼은 하루 ㅋ';
// h1.style.backgroundColor = 'pink';
// }
// 이벤트 핸들러를 이벤트 리스너에 등록
// emoji.addEventListener('click', emojiHandler);
// remove.addEventListener('click', removeHandler);
// h1.addEventListener('mouseover', mouseoverChange);
// h1.addEventListener('click', clickChange);
// [화살표 함수으로 정의 ] ==========================================
emoji.addEventListener('click', (event) => {
console.log(event);
console.log('🎀');
});
remove.addEventListener('click', (event) => {
console.log('이모지 출력 이벤트 해제 /(ㄒoㄒ)/~~');
// emoji.removeEventListener('click', ); // 이벤트 핸들러 해제
});
h1.addEventListener('mouseover', () => console.log('마우스 쥐나가요 ~ ㅋ'));
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});
h1.addEventListener('click', () => {
h1.innerText = '쪼은 하루 ㅋ';
h1.style.backgroundColor = 'pink';
});


module(모듈/기능)
[모듈 가져오기]
- import 키워드 사용
[모듈 내보내기]
- export 키워드 사용
기능이 담긴 자바스크립트 1개 이상의 함수에 한 파일씩 만들어 필요한 html 에 연결
p240530/module/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>모듈</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>모듈</h1>
<script src="index.js"></script>
</body>
</html>
p240530/module/index.js
/*
==========================================
[모듈 가져오기]
- import 키워드 사용
==========================================
*/
console.log('*** index.js 시작 ***');
// 1-1) 방법 1
import { info } from './item.js';
console.log('*** index.js 종료 ***');
p240530/module/item.js
/*
==========================================
[모듈 내보내기]
- export 키워드 사용
==========================================
*/
console.log('*** item.js 시작 ***');
// 1-1) 방법 1
export function info() {
console.log('등록된 상품이 없습니다.');
}
console.log('*** item.js 종료 ***');
처음 보는 error !
웹 브라우저가 html 을 렌더링할 때 호이스팅을 하는데
html 에 index.js 를 읽는데 index.js 에서 다른 파일을 읽어오고 있다고 표시한 것 !

이러한 상황을 알려주기 위해서 html 에 script 에 type 을 지정해줘야한다 !
p240530/module/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<title>모듈</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>모듈</h1>
<script src="index.js"></script>
</body>
</html>
근데

다른 파일을 추가 했는데 test.js 가 먼저 읽는다
근데 코드는 위에서 아래로 읽는데 test.js 먼저 실행될까 !!!!

그 이유는 import 를 한다는게 다른 파일을 참고 하고 있다는 뜻이고
없는 경우 순수 파일로 실행되고 있다 !
자바스크립트는 순서와 상관없이 순수된 파일 먼저 읽고 참조된 파일은 그 후 실행된다
그래서 코드의 가독성을 돕기 위새 코드 순서도 바꾼다 !
그래서 다시 돌아와 파일 실행 순서를 콘솔창으로 확인해보자
index.js 를 읽으면서 호이스팅이 되는데 import 한 파일도 읽으면서 실행이 되고 index.js 가 실행된다

지금 공부 하는 단계라서 그렇지 원래 import 는 맨 위에 선언 해야된다 !
만약 import 를 하는데 같은 경로 같은 파일인 경우 한 번만 읽는다

내보내기를 할 때 function 과 export 를 분리하게 된다면 여러 개를 한 번에 내보내기 가능하다.

그럼 하나 하나 export 를 해야되나 ? 아래 방법 처럼 하면 된다 !
// 1-3) 방법 3
// as : alias (별명/별칭)
import * as obj from './item.js';
obj.info();
obj.edit();
obj.del();
다시 정리하면 ..!
1. named export
[1. named export]
: 이름이 정의된 내보내기 방식
: 함수, 변수 등 왼쪽에 export 키워드 사용
: 한 모듈 내 여러 개 내보내기 가능
[1. '정의된 내보내기'를 가져오기] ----------------------
<<문법>>
import { 이름 } from '경로/파일명.확장자';
: 이름 변경 불가능
p240530/module/item.js
// 1-1) 방법 1
import { info } from './item.js';
info();
// 1-2) 방법 2
import { edit, del } from './item.js';
edit();
del();
// 1-3) 방법 3
// as : alias (별명/별칭)
import * as obj from './item.js';
obj.info();
obj.edit();
obj.del();
p240530/module/index.js
// 1-1) 방법 1 : exprort 키워드를 함수명 왼쪽에 사용
export function info() {
console.log('등록된 상품이 없습니다.');
}
// 1-2) 방법 2 : export 키워드를 별도로 사용
function edit() {
console.log('상품을 수정합니다.');
}
function del() {
console.log('상품을 삭제합니다.');
}
// 여러 개 내보내기
export { edit, del };
2. default export
[2. default export]
: 기본 내보내기 방식
: 한 모듈 내 하나만 default 지정
[2. 'default 내보내기'를 가져오기] ----------------------
<<문법>>
import 이름 from '경로/파일명.확장자';
: {} 반드시 생략, {} 사용하면 error
: 이름 변경 가능
p240530/module/item.js
// 2-1) 방법 1
import add from './item.js';
import Add from './item.js';
import zzz from './item.js';
add();
Add();
zzz();
// 2-2) 방법 2 : default 키워드를 별도로 사용
// 이런 형태가 많이 사용
// 함수 정의를 먼저 하고 나중에 export 하니까 편함
function add() {
console.log('상품이 등록되었습니다.');
}
// 한 파일 내에 default 내보내기는 1개만 가능
// export default function aaa () {}
export default add;
// 2-3) 방법 3 : 익명 함수
// 가져올 때 이름을 변경할 수 있기 때문에 익명 함수도 많이 사용
export default () => console.log('상품이 등록되었습니다.');
p240530/module/hide.js
console.log('*** hide.js 시작 ***');
function show() {
console.log('>> show() 실행 ')
}
// export default show;
export { show as default }; // 요즘은 잘 사용 x
console.log('*** hide.js 시작 ***');
p240530/module/index.js
import add from './item.js';
import Add from './item.js';
import zzz from './item.js';
add();
Add();
zzz();
// 변수에 저장안하고 파일/모듈 만 실행하겠다는 뜻
import './hide.js';
// 같은 모듈을 다른 형태로 import 해도 한번만 실행
// import * as hide from './hide.js';
// default export 가져오기
import show from './hide.js';
import { default as showTwo } from './hide.js';
show();
showTwo();
모듈 다시 내보내기
- 모듈의 보안 유지 가능
p240530/module/hide.js
console.log('*** hide.js 시작 ***');
function show() {
console.log('>> show() 실행 ')
}
// export default show;
export { show as default }; // 요즘은 잘 사용 x
console.log('*** hide.js 시작 ***');
p240530/module/login.js
console.log('*** login.js 파일 시작 ***');
function login() {
console.log('>>> login() 실행 !!!')
}
export default login;
console.log('*** login.js 파일 종료 ***');
p240530/module/secret.js
console.log('*** secret.js 시작 ***');
// hide 모듈 읽고 바로 내보내기
import Secret from './hide.js';
// login 모듈 읽고 바로 내보내기
import Login from './login.js';
// export default Secret, Login;
export { Secret, Login };
console.log('*** secret.js 종료 ***');
p240530/module/index.js
import { Secret, Login } from './secret.js';
Secret();
Login();
'Language > HTML & CSS & JavaScript' 카테고리의 다른 글
[프로젝트] 행복한 마켓 - 1. HTML, CSS 설정 (0) | 2024.05.29 |
---|---|
[JavaScript] innerText 와 innerHTML 차이점 (0) | 2024.05.28 |
[HTML/CSS] float 을 활용하여 ul 태그로 메뉴 레이아웃 잡기 (0) | 2024.05.16 |
[HTML/CSS] float 을 활용하여 레이아웃 잡고, 해제하기 (0) | 2024.05.16 |
[HTML/CSS] table 태그로 테이블 만들고 style 적용하기 (0) | 2024.05.16 |