목차
  1. JavaScript
  2. JavaScript 특징
  3. JavaScript  사용 방법
  4. 내부 스크립트
  5. 외부 스크립트
  6. JavaScript  Error !
  7. JavaScript 변수(Variable) 선언 방법
  8. 변수의 데이터 타입
  9. 1 . 변수에 아무런 값을 넣지 않았을 때
  10. 2. 변수에 숫자(정수/실수) 넣었을 때
  11. 3. 변수에 정수값 넣었을 때
  12. 4. 변수에 문자열 넣었을 때
  13. 5. 변수에 boolean 넣었을 때
  14. 문자열 리터럴
  15. 문자열 관련 함수
  16. 문자열 길이 : length()
  17. 특정 문자 변경 : replace(변경할 문자, 대체할 문자)
  18. 특정 위치의 문자 추출
  19. 특정 문자 기준으로 분리(쪼개기) : split(특정 문자)
  20. 특정 문자 추가 : 문자열.padStart(문자열 전체 길이, 추가할 문자)
  21. 특정 문자 찾기 : include(찾고자 하는 문자열) => true / false 리턴
  22. 특정 문자의 위치(index) 리턴 : indexof(찾고자하는 문자열)
  23. 문자 반복 : repaeat(반복할 횟수)
  24. 대/소문자 변경
  25. 공백 제거
  26. 참조 타입 - 배열
  27. 참조 타입 - 객체
  28. 배열 관련 함수(type05,06)
  29. 객체 축약 표현
  30. 1. 키와 값이 같은 경우
  31. 2. 값이 함수인 경우
  32. 객체 함수(type08)
  33. 객체 구조 분해 할당 - 1
  34. 배열
  35. 객체
  36. 객체 구조 분해 할당 - 2
  37. 연산자
  38. 산술 연산자
  39. 복합대입 연산자
  40. 증감 연산자
  41. 관계 연산자
  42. 논리 연산자
  43. 삼항 연산자
  44. 널리쉬(nullish)
  45. 전개 연산자, 전개 구문(spread sysntax)
  46. 대화상자(dialog-box)
  47. 1. 경고창
  48. 2. 확인창
  49. ★ 확인창 퀴즈 !
  50. 3. 입력창
  51. ★ 입력창 퀴즈 !
  52. 제어문 : 조건문, 반복문
  53. 1-1. 조건문  : swith문
  54. 1-2. 조건문  : if문
  55. 2-1. 반복문: for문
  56. 2-2. 반복문: for in문
  57. 2-3. 반복문: for of문
  58. 2-4. 반복문: while문
  59. 2-5. 반복문: do~while문
  60. 함수 : 내장 함수, 사용자 정의 함수
  61. 1. 내장 함수 : 이미 정의된 함수
  62. 2. 사용자 정의 함수
  63. [함수 정의 형태]
  64. [함수 정의 형태] 1. 매개변수 없고, 리턴값 없음
  65. [함수 정의 형태] 2. 매개변수 없고, 리턴값 있음
  66. [함수 정의 형태] 3. 매개변수 있고, 리턴값 없음
  67. [함수 정의 형태] 4. 매개변수 있고, 리턴값 있음
  68. Arguments 속성
  69. Parameter 속성
  70. 함수 종류
  71. 함수 선언식
  72. 함수 표현식
  73. 즉시 실행 함수 : 1회용
  74. [함수 선언식과 표현식] 생성과 실행 순서
  75. 인수
  76. 중첩 함수
  77. 함수 정의 내 함수 정의, 호출 방법 2가지
  78. 화살표 함수
  79. 화살표 함수 쓰기 전
  80. 화살표 함수 기능 구현
  81. 화살표 함수의 정의 형태
  82. 1. 매개변수 1개, 리턴값 있음
  83. 2. 매개변수 없고, 리턴값 있음
  84. 3. 매개변수 1개, 리턴값 있음
  85. 4. 매개변수 2개, 리턴값 없음, 명령어 여러 개
  86. 5. 매개변수 2개, 기본값 설정, 리턴값 없음, 명령어 여러 개
  87. 호이스팅(hoisting)
  88. var 변수와 let 변수 선언
  89. var 변수와 let 변수 선언, const 변수 선언
  90. 값 변경
  91. scope(스코프) 
  92. 코드 변경 1. 조건문 추가
  93. 코드 변경 2. 변수 변경 var -> let
  94. var
  95. var -> let  변경
  96. 렉시컬 스코프(lexical scope)
  97.  
  98. function 안에 또 function 
  99. [함수] 메모리 할당 시기
  100. 화살표 함수로 변경하기
  101. callback 함수
  102. 동기/비동기
  103. 동기
  104. 비동기
  105. 배열 함수
  106. find
  107. filter
  108. map, forEach
  109. 배열 함수 예제
  110. 일반 for 문과 forEach() 함수 비교
  111. 일반 for문
  112. forEach()함수
  113. map() 함수
  114. closure (클로저)
  115. DOM (document)
  116. 특정 엘리먼트 찾기 1
  117. 특정 엘리먼트 찾기 2
  118. 이벤트
  119. 이벤트 핸들러 등록과 삭제
  120. module(모듈/기능)
  121. 1. named export
  122. 2. default export
  123. 모듈 다시 내보내기

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) 선언 방법

  1. var -> 선언 위치에 따라 다르지만 보통 전역 변수, 기본값이라 생략 가능, var 변수에 함수를 저장하고 다시 값을 저장하면 변경될 위험이 있어 사용하지 않음
  2. let -> 블랙 라벨, 전역에 선언된 let 은 global 영역이 아닌 script 영역으로 들어감
  3. const -> java의 final 와 결이 비슷
  • 하나의 코드를 작성할 때 (;) 를 넣는데, 생략해도 에러 발생 x
  • 초기화하지 않았으면 undefined 값이 보여짐
  • undefined 는 초기화를 하지 않았다는 뜻, null 과 전혀 다름

# p240522/hoisting.html

[var, let, const]
- var 는 함수 레벨 스코프, letconst 는 블랙 레벨 스코프
- var 는 선언된 변수를 선언 전에 접근 가능
- letconst 는 불가능 (error) 
- var 는 이미 선언된 이름과 같은 이름의 변수를 여러 개 선언 가능 (덮어 씌워짐)
- letconst 는 불가능 (error)
- varlet 은 변수 선언과 동시에 초기화를 하지 않아도 되지만,
  const 는 반드시 초기값을 설정해야 함
- varlet 은 값 변경이 가능하지만,
  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     : 정수 [ -(253승-1) ~ (253승-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>

1) ip / 2) port
태그는 의미 없음 !!!!!!!!!!!!!!!!!!

 

2. 확인창

# p240520/dialog-box-confirm.html

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

2개의 버튼

★ 확인창 퀴즈 !

[문제]
truefalse 는 변수를 사용해서 쓰기
확인 버튼을 클릭하면, 
'리턴값은 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>

텍스트 박스에 50 을 입력 후 확인 눌렀을 때 보여지는 웹 브라우저

 

 

<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

[문법]
# 조건 1if (조건식) {
    명령어;
    명령어;
}

# 조건 2if (조건식) {
	true일 때 명령어;
} else {
	false 일 때 명령어;
}

# 조건 3if (조건식 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>

 

실행 순서

hi('박보검')
함수 실행
hi('홍길동')
함수실행

함수 표현식

# 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>

 

실행 순서

hello 엔 f 정보 x
1 , 2 번 중에 1번이 먼저 들어옴
hello('이미자') 실행
이미자 정보 저장

즉시 실행 함수 : 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가지

  1. 함수 내 함수 호출
  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>

 

실행 순서

grolbal 영역 : result 와 createHello() 은 들어옴
local 영역에 hello() 가 들어옴
stack 영역 : 현재 실행중인 함수
2번째 사진 설명 : 변수에 값이 덮어지지 않는 한 프로그램이 종료 되어도 저장되어있음

 

# 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>


실행 순서

global 영역에 들어온 것을 확인할 수 있음
inner () 정보 x
local 은 실행될 때 사용됨

 

# 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>

변수 선언 전에 미리 할당됨
문구 출력
값 설정을 안했기 때문에 undefined
a_hi 라인 처리가 되면서 초기화 작업이 이루어짐
breakpoint 가 끝나면서 디버깅이 끝나느데 그래서 영역이 사라짐

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>

 

실행 순서

var 변수는 global 영역에, let 변수는 script 영역에 들어옴
let 변수는 값 설정을 해줘야함

 

그럼 다시

<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 변수는 undefined 값이 들어오고, let 변수는 값 처리가 안됨
let 은 호이스팅은 되지만 값이 처리 되지 않은 let 변수는 사용할 수 없다는 것을 알 수 있음!

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>

 

실행 순서

let 과 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>

 

실행 순서

만약 var 변수명이 script 영역에 있으면 script 영역에 있는 변수에서 값설정이 되고, global 영역에 생기지 않음, const 는 값 설정 x

 

 


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>

실행 순서

a_body_var 가 호이스팅이 안된 이유는 아직 script 태그를 읽지 않았음
라인 처리가 되면서 값 설정이 됐음
body 에 있는 script 태그를 읽으면서 a_body_bar 가 호이스팅 됨
메모리에 할당되었기 때문에 사용이 가능함

 

만약 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>

 

실행 순서

지역 변수는 아직 호출이 안됐으니까 메모리 할당 안된 것이 맞음
CallStack 에는 현재 실행(호출) 중인 코드가 들어옴
메모리 할당 되었으니 값을 사용할 수 있다 !
프로그램이 종료되면서 지역변수에 있는 값은 메모리에서 사라짐

 

코드 변경 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>

function 이 실행되면 local 에 들어오면서 조건문이 끝나도 아직 실행이 끝나지 않았기 때문에 메모리에 남아 있어서 값을 사용할 수 있음

코드 변경 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>

 

실행 순서

let 은 실제 라인이 처리될 때 값 설정이 돼서 아직 메모리에 할당되지 않았음
값이 없기 때문에 error 가 뜨면서 실행 종료가 됨, 접근이 안됨
let , const 는 block scope
값이 없기 때문에 주석 처리하는 것이 맞음, 사용하지 못함

 

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 는 function 내에 선언되지만 않으면 global 영역으로 들어옴, 전역 변수 !

 

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>

let 은 지역변수라서 라인 실행되기 전까지 메모리 할당 x
실행이 끝나면서 메모리가 사라진 것을 확인 할 수 있음


렉시컬 스코프(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>

상위 scope 를 찾아감

 

# 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>

 

실행 순서

global 영역에 들어옴 !
a_num 5 값이 들어옴
실행 되면서 a_you 함수에 정의된 a_num 이 hoisting 됨
a_need() 실행되면서 hoisting 됨
근데 사라짐 ! 그 이유는 상위 스커프가 a_you() 가 아니기 때문 !


[함수] 메모리 할당 시기

#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>

 

실행 순서

script 태그를 읽으면서 global 영역에 메모리 할당
add 함수가 실행 되고 있음
화살표 함수는 global 영역에 x

동기/비동기

<네트워크 기준>
[동기] - 시간을 맞추는 것
클라이언트가 서버한테 무언가를 요청할 때, 
서버가 응답할 때까지 클라이언트는 작업을 하지 않는다.
[비동기]
클라이언트가 서버한테 무언가를 요청할 때,
서버가 응답할 때까지 클라이언트는 다음 작업을 먼저 한다.

 

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>

 

실행 순서

중지점 찍기
global 영역에 올라온 outer() / 자바스크립트를 실행하기 위해 익명 함수 실행(기본)
outer() 호출되면서 함수가 실행되었기 때문에 local 영역에 count 와 inner() 메모리 할당

 

<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 영역 종료 ...

실행 순서

중지점 설정
outer() 호출되면서 실행됐기 때문에 메모리 할당

 

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';
});

이벤트 해제 후 이모지 출력 버튼 클릭해도 이벤트 발생 x


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();