한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 by 이정환
JavaScript는 오늘날 가장 많이 사용되는 프로그래밍 언어다.
요소들의 내용, 배치, 모양을 정하기 위해 사용하는 언어 -> 웹 사이트에 들어갈 내용 담당
색상이나 디자인 등의 수정은 불가 -> CSS를 사용해야 함
요소들의 색상, 크기 등의 스타일을 설정할 수 있음 -> 웹 사이트에 들어갈 스타일 담당
웹 내부에서 발생하는 다양한 기능을 만들 수 있는 언어
웹을 움직이게 하는 "웹의 근육"이라고 표현
html의 <button>에 onclick 이벤트 발생 시 onClick() 함수가 실행됨
-> 클릭 완료! 란 알람을 띄우게 됨
- 사용자가 버튼을 누름
onclick="onClick()"이 호출됨onClick()함수 실행alert("클릭 완료!")창 표시
정리하자면,
뼈대를 만드는 HTML, 살을 붙이고 옷을 입는 CSS, 상황마다 동작을 다르게 해주는 JavaScript라고 생각하면 되겠다.
JavaScript는 "JavaScript 엔진"이라는 프로그램을 통해 실행
-> JavaScript 엔진이 없으면 JavaScript 실행은커녕 해석도 불가능
마치 Like 닌텐도 같은 게임 구동기
닌텐도 게임 구동기(스위치)가 없으면 아무리 게임 칩이 많아도 게임을 못하는 것과 같다.
JavaScript 엔진은 우리가 자주 사용하는 크롬이나 사파리 같은 웹 브라우저에 탑재
-> 우리가 웹 브라우저를 이용하면 간단한 JavaScript 코드를 작성하고, 또 실행이 가능
웹 개발을 할 때 필요한 도구를 모아둔 패널
F12command + option + i
undefined는 무시해도 된다...
라고 써 있고, Live Server 플러그인 사용 방법이라 읽어본다...
VS Code 에서 해당 플러그인 설치
console.log("chapter3");
chapter03.js
이 JavaScript 코드를 브라우저로 실행하기 위해서
-> 이 JavaScript 파일을 불러와, 웹 브라우저한테 실행하도록 전달해줄 매개체인 html파일 필요
<html>
<head>
<script src="./chapter03.js"></script>
</head>
<body>
Hello World
</body>
</html>
index.html
<script>태그는 JavaScript 파일을 불러오는 태그
src에 어떤 JavaScript를 불러올 건지 기재
-> index.html 파일이 웹 페이지에 랜더링되면서, <script> 태그에 의해 chapter03.js 파일이 로드됨
ctrl + shift + pcommand + shift + p
index.html 파일을 열어두고 Live Server: Open with Live Server 열기
-> 해당 index.html을 렌더링한 웹 페이지가 열림
중요한 건!
이제는 코드를 수정하면 자동적으로 웹 페이지가 다시 렌더링된다.
Live server 플러그인은 코드의 변경 사항이 발생하면 자동으로 페이지를 새로고침 해줌
-> 웹 페이지가 다시 렌더링되고 JS 파일도 재실행됨
VS Code 우측 하단에 있는 Port 옆에 종료 버튼 클릭
-> 위와 같이 팝업창과 함께 종료
<script> 태그로 JavaScript를 불러올 때 파일이나 경로에 오타가 없는지 확인값을 저장하는 박스 또는 저장소
"Hello" 같은 문자열 값이나,
970107 같은 숫자 값이나,
[1, 2, 3] 같은 배열 값을 저장할 수 있는 어떠한 "공간"
<html>
<head>
<script src="./chapter04.js"></script>
</head>
<body>
Hello World
</body>
</html>
index.html
console.log("Chapter 4");
chapter04.js
age라는 변수에, 27이란 값이 담김
let이라는 키워드와 함께, 변수를 새로 생성하는 과정
선언과 동시에 어떤 값(여기선 27)을 저장하는 과정
= 변수에 초깃값을 넣는다.
-> 변수를 초기화한다.
이제 27이라는 값을, age라는 변수의 이름으로 불러서 사용 가능
위와 같이 age를 출력하면,
위처럼 age에 저장되어 있던 27이 출력됨
-> console.log함수를 사용하여 변수의 값이 개발자 도구 콘솔 탭에 출력이 됨
위와 같이 age라는 변수의 값을 30으로 바꾸고 age를 출력하면,
30이 출력됨
변수는 언제든 값을 바꿀 수 있기 때문에,
선언할 때 초깃값을 설정해주지 않아도 됨.
-> 초깃값이 없는, 즉 초기화가 이루어지지 않은 채로 변수 선언도 가능
단, 초기화가 이루어지지 않은 변수를 출력하게 되면,
결괏값은 undefined가 됨
let이란 키워드로 만든 변수는 이름으로 서로 구별따라서 특수한 경우가 아니면 중복된 이름으로 재선언하는 건 불가능
➡️ 즉, 변수라는 건 프로그램이 실행되는 도중에 값을 바꿔가면서 저장할 수 있는 저장소
상수 역시 변수와 마찬가지로, 값을 저장하는 어떠한 저장소
차이점이 있다면, 상수는 변수와는 달리 한 번 저장된 값을 다시는 바꿀 수 없음
변수를 선언했던 let과 달리 const란 키워드를 사용
이렇게 선언하고 초기화(값을 저장)하는 건 변수와 동일하지만,
초기화 이후에는 값을 바꿀 수 없음
-> 바꾸려고 하면 에러 발생
따라서, 상수는 생일처럼 변할 수 없거나 변하지 않을 값을 저장할 때 변수 대신 사용
값을 변화시키는 것 자체가 불가능하기 때문에 초기화가 반드시 필요!
-> 초기화 없이 선언하면 에러 발생
상수는 선언 이후에는 절대 값을 넣을 수 없기 때문에 무조건 선언과 동시에 초기화 필수!
변수와 상수 모두 값을 저장하는 점과, 자신만의 이름을 갖는다는 점은 동일
-> 변수와 상수의 이름을 정하는 행위 = 변수 명명 or 변수 네이밍
But, 네이밍은 원하는 대로 자유롭게 하되 지켜야 할 규칙 존재
이걸 모르면 선언 시 에러가 발생하거나 의도치 않은 동작 발생
변수와 상수 모두, 변수로 통칭
$, _ 제외한 기호 사용 불가능
그외 기호 사용 시 에러 발생
정 숫자로 시작하고 싶은 경우 _와 같은 문자를 먼저 사용
JavaScript가 이미 특수한 의미로 사용하기로 약속한 단어
조건문을 사용하는 if 키워드의 경우 예약어이기 때문에 사용이 불가능
위 3번의 명명 규칙을 지켰다고 좋은 변수인 건 아님
위 변수 선언의 경우 각각의 변수가 무엇을 의미하는지 알 수 없음🤔
이렇게 변수를 명명하면, 협업하는 과정에서는 큰 문제가 발생할 수 있음
(아마 실무에서 이렇게 변수 선언했다간 그 회사에서 두고두고 내려오는 전설 될 수 있음.)
누가 봐도 이해할 수 있는 변수명을 명명하는 것이
추후 수정하거나 협업 시 알아보기 편함
영어로는 Type
값을 포함하는 집합
동일한 성질(속성이나 특징)을 가지고 있는 원소를 묶은 것
그럼 즉, 자료형(Type)이란 동일한 성질을 가진 원소들, 대상을 묶은 것
강아지와 고양이를 동물이란 집합에 묶을 수 있는 것처럼 JavaScript 세상에 존재하는 여러가지 값 중에
문자열이라고 부르는 값을 묶으면
-> String 자료형, String 타입이라 할 수 있음
숫자라고 부르는 값을 묶으면
-> Number 자료형, Number 타입이라 할 수 있음
자료형은 원시 타입과 객체 타입으로 나뉘는데
이번 시간에는 원시 타입만 다루는 것으로...
원시 타입 = 기본형 타입
: 지금은 프로그래밍에 있어 가장 기본적인 데이터들의 타입
나머지 연산은 모듈러 연산이라고 함(참고사항)
위와 같이 선언할 수가 있음
자바스크립트는 이 두 값을 내부적으로 특별한 Number 타입의 값으로 다루고 있음
근데 0으로 어떻게 나누죠?
자바스크립트는 IEEE 754 부동소수점 표준을 따르기 때문에, 0으로 나눌 때 예외(에러)를 던지지 않고 위와 같은 특별한 숫자 값을 반환한다고 함
Not a number
= 수치연산이 실패했을 때의 결과 값으로 보통 사용
JavaScript에서는 연산에 실패해도 NaN을 출력하기 때문에 불가능한 수치 연산을 이행해도,
프로그램이 완전히 종료되거나 하지 않음
-> JavaScript는 수학 연산에서 안전한 편
JavaScript에서는 문자열 값은 이렇게 무조건 쌍따옴표나 또는 작은따옴표로 감싸주어야 함
쌍따옴표를 하지 않으면, 문자열이 아닌 변수명으로 취급함으로써, 만든 적이 없는 변수명의 경우 오류가 발생하게 됨
각각 문자열에 저장된 문자열이 이어붙여짐
쌍따옴표와 기본적으로 비슷하지만, 변수의 값을 동적으로 넣을 수가 있음
-> 템플릿 리터럴 문법이라고 함
앞으로 자주 쓰고 실무에도 유용하다고 함
참이나 거짓을 저장
어떠한 형태의 상태를 의미
ex) 스위치가 켜져 있거나, 비어 있지 않다거나,
아무것도 없다.
empty 라는 변수에 지금 어떠한 값도 들어있지 않다, 라는 의미를 표현
-> null 이라는 값은 이렇게 어떠한 변수에 아무런 값도 담겨 있지 않음을 표현하기 위해서 사용
따라서,
null type은 이러한 null을 포함하는 타입이라고 생각해주면 됨
Null 타입처럼 Undefined 라는 단 하나의 값만 포함
Undefined 라는 값은, 우리가 변수를 선언하고 진짜 그 변수에 어떠한 값도 집어넣지 않았을 때 자동으로 할당되는 값
위와 같이 변수를 선언했는데, 초기화하지 않은 경우,
undefined 가 출력됨
null을 할당해야 함)어떤 값의 타입(자료형)을 다른 타입(자료형)으로 변경하는 것
형 변환을 타입 캐스팅이라고도 함
넘버 타입의 값(숫자값) 10을 문자열 "10"으로 바꾸려는 행위
이러한 형 변환은 두 가지 방식이 있다.
묵시적 변환
-> 암묵적으로, 내가 뭘 하라고 얘기하지 않아도 JavaScript 엔진이 눈치껏 변경하는 것
명시적 변환
-> 명시적으로 내가 "어떤 타입으로 이 값을 바꿔줘."라는 명령을 통해 값의 타입이 변경되는 것
쉽게 말하면
묵시적은 내가 생각지도 못하게 바뀔 수 있는 것
명시적은 내가 시켜야만 바뀌는 것
JavaScript 엔진이 스스로 알아서 변환하는 작업
num에 저장된 숫자값 10이 덧셈하는 과정에서, 묵시적으로 String타입으로 형 변환이 됨result에는 문자열 10과 문자열 20이 더해진 값이 저장result의 값인 1020이 출력됨이렇게 숫자와 문자열을 더하는, 불가능한 연산을 작성하게 되면,
JavaScript 엔진이 오류를 발생시키지 않기 위해서,
이렇게 숫자를 문자열로 변환하는 작업을 암묵적으로 혹은 묵시적으로하게 됨
모든 불가능한 연산에 묵시적 형 변환이 일어나는 것은 아님!
특정 하나의 변수의 값을,
이 예시의 경우 num이라는 변수 하나의 값을 형 변환했을 때,
오류가 발생하지 않고 연산이 잘 종료할 수 있는 경우에만
묵시적 형 변환이 일어남
내장 함수 등을 이용해 프로그래머가 의도적으로 어떤 자료형을 다른 자료형으로 변경하는 작업
Number함수 Number
= JavaScript가 기본적으로 제공하는 내장 함수
-> 인수로 받는 문자열을 숫자로 변환해 반환
이후 숫자 연산이 가능해짐(당연함. 숫자니까.)
10이라는 문자열을 값으로 가지고 있는 strA을
Number 함수로 넣으니
10이란 숫자를 반환하여 numA에 저장
그러나, 변수 strB처럼 숫자가 아닌 문자를 포함한 문자열은 정상적으로 변환되지 않고 NaN을 반환
(NaN = Not a Number)
parseInt숫자뿐만 아니라 (숫자가 아닌)문자도 함께 포함된 문자열을 숫자로 변환하고 싶다면, 함수
parseInt사용
parseInt(strA, 10);
-> 변수 strA와 10을 인자로 전달하면, 문자열 strA를 10진수 숫자로 형 변환
문자열에서 숫자만 추려 반환하기 때문에, 문자와 숫자가 섞여있는 문자열도 숫자로 변환 가능
(참고로 두 번째 인자를 생략해도 보통 10진수로 변환하는 것으로 보이나, 안정적으로 사용하기 위해선 진수를 쓰는 것이 좋을 것 같음)
위와는 달리 "10개"라는 숫자와 문자가 섞인 문자열을 값으로 가진 strB도 숫자로 변환
단, 함수 parseInt가 동작할 때는 문자열의 첫문자부터 숫자로 변환하므로,
문자열이 숫자가 아닌 문자로 시작한다면 NaN을 반환
위와 같이 문자로 시작하는 문자열은 숫자를 파싱해서 반환할 수 없음
그럼 숫자로 시작하되, 숫자와 문자가 뒤섞인 문자열은 어떨까? 싶어 코드를 짜봄
그렇다고 함
무조건 문자가 나오면 그 앞 숫자까지 파싱하는 모양
String함수 String
= JavaScript가 기본적으로 제공하는 내장 함수
-> 인수로 받는 숫자를 문자열로 변환해 반환
변수 num에 저장된 숫자 2025를 함수 String을 이용해 문자열로 변환
출력된 값이 숫자인지 문자열인지 결과만 보고 알 수 없으므로
typeof로 자료형도 출력해봄
varA : 초기화되지 않은 변수varB : null 값이 할당된 변수varC : true가 할당된 변수
해당 변수 자체의 값들을 그대로 문자열로 변환하기 때문에
변환된 값을 출력하면 변수 자체의 값이 출력
Boolean불리언 값으로 변환하는 내장 함수
"하이" -> true0 -> falsefalseJavaScript에서 불리언 변환은 truthy & falsy 규칙을 따름
여기서는 특정 값을 불리언으로 변환하면 true 혹은 false를 반환한다만 기억
+,-,*,/등과 같이 프로그래밍 언어에서 다양한 연산을 수행할 때 도움을 주는 기호 또는 문자
JavaScript는 기본 사칙연산 외에도 여러 형태의 유용한 연산을 수행할 수 있는 다양한 연산자 제공
=가장 기본이 되는 연산자
변수에 값을 할당하는 역할
대입 연산자 =의 왼쪽에는 값을 저장할 변수를,
오른쪽에는 값이나 또 다른 변수 지정
대입 연산자를 사용할 때 피연산자의 결합 방향은 오른쪽에서 왼쪽으로 진행
같은 수식 내에, 우선순위가 같은 연산자가 둘 이상 있을 때,
어느 연산을 먼저 수행할지 결정하는 일
-> 따라서 연쇄적인 할당이 가능
대입 연산자의 결합 방향은 오른쪽에서 왼쪽이므로
-> numC = numA 먼저 수행
-> numB = numC 수행
따라서 모든 변수에 값 1이 동일
덧셈(
+), 뺄셈(-), 곱셈(*), 나눗셈(-), 나머지 연산(%)처럼 프로그래밍에 필요한 가장 기본적인 계산 기능 수행
대입 연산자와 산술 연산자의 기능을 함께 이용할 때 사용
이미 값이 들어 있는 어떤 변수에 10을 더하려면
위 코드를 복합 대입 연산자로 사용하여 더 간단하게 표현 가능
복합 대입 연산자는 산술 연산자와 대입 연산자를 서로 이어 붙여(+=) 사용
number는 계속 재사용되어, 각각의 연산의 결과값을 담음
-> 덧셈 연산으로 20, 거기에 뺄셈 연산으로 10,... 되는 식
값을 1씩 늘리거나 줄일 때 사용
위와 같이 증감 연산자를 변수 뒤에 두면,
증감 연산의 결과는 연산자가 있는 다음 행부터 반영
무슨 뜻이냐면
피연산자인 변수 뒤에 증감 연산자를 두는 것을 후위 연산이라고 하며,
이 연산의 결과는 다음 행부터 적용
1 출력2 출력1 출력0 출력
피연산자인 변수 앞에 증감 연산자를 두는 것을 전위 연산이라고 하면,
이렇게 하면 증감 연산을 작성한 행에서 연산 먼저 반영
2 출력2 출력0 출력0 출력참(true)와 거짓(false)을 포함하는 불리언 값을 다룰 때 사용하는 연산자
| 논리 연산자 | 설명 |
|---|---|
| OR(ㅣㅣ) | 둘 중 하나라도 참이면 참 |
AND(&&) | 둘 중 하나라도 거짓이면 거짓 |
| NOT(!) | 참은 거짓, 거짓은 참 |
AND 연산과 OR 연산은 두 개의 피연산자를 사용하지만,
NOT 연산자는 하나의 피연산자만 사용
전원 스위치의 on/off처럼 참을 거짓으로, 거짓을 참으로 바꾸는 기능
= 토글(Toggle)기능
정답은 모두 상쇄되어서 true
두 값을 비교하는 연산자
| 비교 연산자 | 설명 |
|---|---|
| === | 같다. |
| !== | 같지 않다. |
| > | 크다. |
| >= | 크거나 같다. |
| < | 작다. |
| <= | 작거나 같다. |
동등 비교 연산자라고도 함
변수 numberA와 numberB가 같은 값을 가짐.
-> 출력 결과: true
변수 numberB와 numberC의 값은 같아 보이지만, 두 변수의 자료형은 숫자형과 문자형으로 각각 다름
-> 출력 결과: false
자바스크립트를 배우기 이전에 다른 언어를 조금이라도 다뤄본 사람이라면(나)
===가 어색할 수 있음((나))
왜냐하면 다른 언어에서는 보통 값이 동등한지 비교할 때 ==를 사용하기 때문
자바스크립트도 ==연산자를 사용할 수 있지만, 이는 정말 "값"만 비교할 뿐,
자료형은 비교하지 않기 때문
C나 자바의 경우, 애초 타입이 정해진 변수(int, char 등)에 값을 넣기 때문에 이미 자료형이 구분이 되니까 ==를 써서 값만 비교해도 되지만,
자바스크립트의 경우 변수의 타입이 불명해서, 값만 비교하느냐 값과 자료형을 비교하느냐 옵션이 있는 걸까?
아무튼 값과 자료형을 모두 비교하는 ===연산자를 사용할 때는 거짓으로 나온 결과가,
==연산자를 사용할 때는 값만 비교하므로 결과가 참으로 나온다.
동등 비교 연산자(
===)에서 맨 앞의=를!로 바꾼!==연산자 사용
두 값이 다른지 비교
!== 연산자는 값과 자료형 중 하나라도 다르면 참으로 판단.
!= 연산자는 자료형은 비교하지 않고, 값이 다르면 참으로 판단.
아는 것이니까 넘어간다.
null병합 연산자(Nullish Coalescing Operator)는 값이 확정된 변수를 찾을 때 사용
자바스크립트에서는 값이 '없음'을 나타내는 자료형으로 null과 undefined가 있음
null이나 undefined가 있는 변수를, 값이 확정되지 않은 변수라고 함
null 병합 연산자 ??을 사용하면,
-> 값이 확정된 변수를 쉽게 찾을 수 있음
varA의 값은 10, varB의 값은 20으로 둘 다 값이 확정
이때 null 병합 연산에서는 ?? 연산자 기준 왼쪽의 값을 연산 결과로 반환
varB의 값은 20, varC는 값을 할당하지 않아 undefined 값을 가짐
이때 null 병합 연산에서는 값이 확정된 변수인 varB의 값을 연산 결과로 반환
요구사항
변수user에 해당 사용자의 이름이 있다면 이름을, 이름이 없다면 닉네임을 저장
변수 name과 nickname 중 확정된 변수의 값을 user에 저장
-> name에는 값이 없으므로 변수 user에는 nickname의 값이 저장
만약, 변수 name에 값을 확정한다면?
null 병합 연산자는 두 피연산자의 값이 모두 확정되면,
왼쪽의 값을 결과로 반환
자바스크립트는 변수에 숫자를 저장했다가 문자로 바꿔서 저장해도 오류가 발생하지 않음
-> 변수를 담는 자료형에는 제한이 없기 때문
자바스크립트 변수는 값을 저장할 때마다 자료형이 동적으로 결정
저장하는 값에 따라 변수의 자로형이 함께 변경되는 특징 === 동적 타이핑(Dynamic Typing)
이거시 자바스크립트의 유연함,
그러나 이건 때로 단점이 됨
프로그램이 의도치 않게 동작하거나 오류 발생 가능
변수 varA의 값을 숫자형으로 오인하고, 증감 전위 연산자를 사용
-> 이 경우 NaN을 출력하여 의도한 대로 동작하지 않음
(문자열 "ann"은 숫자로 바꿀 수 없으므로 NaN이 됨)
이런 상황을 대비해 변수 varA의 자료형이 무엇인지 선확인 필요
-> typeof 연산자를 이용하면, 변수의 자료형 확인 가능
typeof 연산자는 앞으로 배울 조건문에서, 변수의 자로형에 따라 각기 다른 코드를 수행하도록 만들 때 사용
조건식 ? 조건식이 참일 때 수행할 명령 : 조건식이 거짓일 때 수행할 명령
varA는 string이기 때문에 console.log("문자 자료형")이 수행
또한 삼항 연산자는 조건식에 따라 다른 명령을 수행할 때 사용하지만,
값을 반환하기도 함
삼항 연산자에서 참과 거짓에 따라 수행하는 명령 대신에 값을 입렵하면,
조건식에서 정한 값 반환
-> num % 2 === 0이 아니므로, 변수 result에는 홀수라는 문자열이 할당
특정 조건을 만족할 때 원하는 동작을 수행하게 하는 프로그래밍의 기본적인 문법 중 하나
내가 잘 아는 파트이니 간단히 짚고 넘어가겠음
if (조건식) {
조건식이 참일 때 수행할 명령
}
if (조건식) {
조건식이 참일 때 수행할 명령
} else {
거짓일 때 수행하는 명령
}
if (조건식1) {
조건식1이 참일 때 수행할 명령
} else if (조건식2) {
조건식2가 참일 때 수행할 명령
}else {
거짓일 때 수행하는 명령
}
else if문은 두 개 이상의 조건이 있는 경우에 사용
중첩 if문처럼 비교할 조건이 많을 때 사용하는 조건문
식이나 값을 case문과 비교해 정확히 일치할 때만 수행
fruit의 값을 기준으로 이 값이 어떤 case에 해당하는지 판단apple이므로 이 case문의 조건과 일치switch문에서는 case문에서 수행할 명령을 작성하고,
break문을 입력해 "실행할 명령이 끝났으니 switch문을 종료하라"고 알려줘야 함
만약 break를 입력하지 않으면,
조건식과 일치해 실행한 case문 이후의 명령까지 모두 차례로 수행
(오류가 나지는 않음)
위처럼 사과만 출력하지 않고, 줄줄이 수행하는 것을 볼 수 있음
switch문은 조건식과 일치하는 case문의 명령을 수행한 후에도,
다음에 작성한 명령까지 모두 수행하려는 속성이 있음
-> 적절히 break문을 입력해 원하는 case문만 수행하도록
default문은 비교하는 식 또는 값이 어떤 case와도 일치하지 않을 때 수행하는 명령
default문은 선택적으로 사용 가능, 생략해도 오류가 발생하지 않음
조건이 여러 개인 경우, 중첩한 else-if문 대신에 switch문 사용 시 좀 더 가독성 있는 코드를 작성 가능
보통 조건의 개수는 많지만, 조건별로 수행할 식이 짧은 경우 -> switch문 사용
for (초기식; 조건식; 증감식) {
실행할 명령
}
for문은 조건식과 일치하지 않을 때까지 반복하면서 중괄호에 있는 명령 수행
,)로 구분++이나 --와 같은 증감 연산자를 사용하기도 하고, 복합 대입 연산자를 쓰기도...break문을 사용하면 조건식에서 정의한 반복문의 종료 조건과 상관없이,
반복 강제 종료 가능
continue문을 사용하면, 다음 반복 과정으로 건너 뜀
짝수면 continue를 만나 console.log(i)를 수행하지 않고,
다음 증감식에 도달해 다음 반복문을 수행
위 이미지처럼 중복으로 작성된 유사한 기능을 하는 코드가 여러 곳에 있다면,
따라서 생산성이 떨어지고 유지보수 하는 데에도 문제
=> 함수로 해결
여기저기에서 공통으로 사용되는 코드를 이름으로 대체, 기능을 불러올 수 있다.(호출)
= 간단하고 편하게 기능을 가져다 쓸 수 있는 문법
키워드 - 함수 이름 - (소)괄호 - 중괄호
함수를 새로 만드는 일
= 함수 선언
그러나, 함수는 선언했다고 실행되는 게 아님
-> 호출해야 실행됨
즉, 함수 선언이란,
함수가 호출되었을 때 어떤 코드들을 실행할 것인지 미리 준비해두는 작업
또한 함수가 호출되면 코드의 실행 흐름이 마치 포탈을 타고 이동하는 것 같음
-> 코드를 실행하다 호출 부분을 만나면 해당 함수 내부의 코드 실행
따라서 프로그램 실행 순서가 바뀜
이런 식으로 활용,
But, 위 코드는 정적임
항상 고정된 가로와 세로 길이를 가진 영역만 구할 수 있음
가로와 세로 길이를 동적으로 가질 수는 없을까?
-> 소괄호에 변수를 써서, 매개변수로 값을 전달하자!
함수 호출 시 소괄호 안에 전달할 값 기재 -> 이때 전달할 값 === 인수
전달 받은 인수를 순서대로 저장한 값 -> 함수의 변수 === 매개변수(매개체 역할을 하는 변수)
함수 실행문에 return 키워드를 쓰면, 해당 키워드 이후의 값들을 반환 (=반환값)
즉, 함수 호출의 결과값
return문 이후의 코드는 실행되지 않는다.
함수 안에 함수를 선언할 수 있음
자바스크립트에서는 함수의 선언을 함수의 호출보다 아래에 선언해도 문제 없이 수행
= 자바스크립트의 호이스팅 기능
(C나 JAVA 등 다른 언어에서는 없는 기능)
밑바닥에 작성된 선언문을 최상단으로 끌어올려 실행하는 기능
(이게 생각보다 어려운(?) 심도 있는(?) 개념임)
아무튼 따라서 자바스크립트에서는 좀 더 유연하게 프로그래밍이 가능
함수를 생성하고 변수에 값으로 저장하는 방식
자바스크립트에서는 함수를 숫자나 문자열 같은 값으로 취급
-> 변수에 함수를 저장 가능
funcA 함수 선언varA에 함수 할당 -> 변수의 초깃값으로 함수를 담음
varA 출력 시 함수 구문이 출력
=> 이렇게 함수를 어떤 변수에 담게 되면, 해당 변수의 이름으로 함수 호출 가능
그래서 함수를 굳이 선언하지 않고
이렇게 함수를 만들자마자 변수에 담는 것도 가능
위 funcB의 경우 선언식이 아님
함수 선언식은 어떤 변수의 값으로 담기지 않은 상태로 유지되어야 함
위와 같은 경우, 값으로서 함수가 생성된 것이므로 함수의 이름으로 호출 불가능
즉,
funcB();
이렇게 함수명으로 호출 불가능
따라서,
어차피 못 쓸 함수명, 굳이 쓰지 말고
위처럼 생략하기도 함
=> 익명 함수 (이름이 없다.)
funcA처럼 함수 선언문을 이용해서 함수를 만들지 않고,
대신에 varB처럼 값으로써 함수를 생성하는 방식 === 함수 표현식
함수 표현식으로 만든 함수는, 값으로 취급되기 때문에,
호이스팅의 대상이 되지 않음
함수 표현식은 콜백 함수에서 유용하게 활용될 것
함수를 이전보다 더 빠르고 간결하게 생성
let varC = function() {
return 1;
}
위처럼 간단하게 표현 가능.
근데 여기서,
한 번 더 간결하게 가능!
varC라는 함수가 값을 반환하기만 한다 하면
중괄호와 return문도 제거 가능
refactorVarC라는 함수는 매개변수를 아무것도 받지 않고 1이라는 값을 반환
-> 중괄호 활용
화살표 수 내에서 몇 가지 추가 작업이 이루어져야 한다면,
중괄호와 return 문을 추가하면 됨
내가 자바스크립트 공부하면서 제일 어려웠던 개념 중 하나
자신이 아닌 다른 함수에 인수로써 전달된 함수
main 함수는, 매개변수를 가지고,
sub 함수는, 문자열을 출력하는 함수
만약,
이라면?
-> sub함수는, main이란 함수의 인수로 값으로써 전달
= main 함수의 value라는 매개변수에, sub라는 함수가 들어옴
그렇기 때문에 이 value 매개변수에 저장된 함수(sub)를 이 main 함수 안에서 호출도 가능
(왜냐하면 value라는 매개변수 안에는 sub라는 함수가 저장 되어 있으니까)
결과는?
sub라는 함수가 호출되어서 내부의 console.log("sub");를 실행
이와 같이 sub함수처럼, main이라는 다른 함수에 인수로써 전달된 함수를,
콜백 함수라고 부름
사실 아직 느낌만 온다...
자바스크립트에서는 이렇게 함수도,
문자열이나 숫자와 같이 값으로 취급되기 때문에
함수 자체를 다른 함수의 인수로 전달하는 게 가능
-> 함수 자체를 출력하기 때문에 sub함수의 구문이 호출
우리 말로 범위
우리가 만든 어떤 변수나 함수에 접근하거나 호출할 수 있는 범위
함수 바깥에서, a라는 변수에 접근해서 해당 값을 출력하려고 하면?
-> 오류 발생
왜냐하면, funcA라는 함수 바깥에서는 변수 a를 알 수 있는 방법이 없기 때문
변수 a가 선언된 영역은 funcA라는 함수 내부
그렇기 때문에 a라는 변수에 접근할 수 있는 범위는, 즉 스코프는,
이 함수 내부로만 한정
-> 이 함수 바깥에서는 a라는 변수에 접근할 수 없음
이렇게 변수 등에 접근할 수 있는 영역을 스코프라고 함
변수 a는 funcA라는 지역 스코프를 갖는다 or 지역적인 스코프를 갖는다, 라고 표현
| 종류 | 설명 |
|---|---|
| 전역 스코프 | 전체 영역에서 접근 가능, 어떤 함수나 블록에도 속하지 않고, 프로그램 전체에서 접근 가능한 영역 |
| 지역 스코프 | 특정 영역에서만 접근 가능, 특정 함수나 블록 내부에서만 접근할 수 있는 영역 |
변수 a와 함수 funcA는 어디서든 접근이 가능하므로, 전역 스코프를 가짐
어떠한 함수, 반복문, 조건문에 갇히지 않은 바깥 영역에 선언하면, 어디에서나 해당 변수, 함수에 접근 가능
변수 b는 선언된 함수 내에서만 접근이 가능하므로, 지역 스코프를 가짐
변수가 현재 선언된 영역 안에서만, 해당 변수에 접근 가능
조건문도 중괄호로 블록을 만들기 때문에
블록 내에 선언된 변수는 지역 스코프를 가짐
반복문도 중괄호로 블록을 만들기 때문에
블록 내에 선언된 변수는 지역 스코프를 가짐
반복문의 초기식(let i = 0)도 마찬가지
함수도 스코프를 가짐
funcFuncC는 funcC의 내부에 선언되었기 때문에
funcC외부에서는 funcFuncC 호출 불가
함수도 변수처럼 똑같이 지역 스코프를 가짐
원시 타입이 아닌 객체 타입의 자료형
여러 가지 값을 동시에 저장할 수 있음
-> 객체를 이용하면 현실 세계에 존재하는 사물이나 개념을 자바스크립트 값으로 쉽게 표현
let ann = {
name: "annyj",
nickname: "annmmww",
birth: "0314",
}
ann이라는 객체에 이름, 닉네임, 생일이란 정보를 담아서 표현할 수 있음
객체 리터럴이 훨씬 더 간결해서, 대부분 해당 방법 이용
person이란 객체 안에 어떤 특정한 한 사람을 표현한 값을 저장
위 코드에 기재된 객체 안의
name, age, hobby는 객체의 정보 값 === 객체 프로퍼티(객체 속성)
-> 객체의 실질적인 정보를 담는 역할
프로퍼티는 콜론(:)을 기준으로
왼쪽에 프로퍼티 이름 역할을 하는 키(key),
오른쪽에 프로퍼티의 값인 밸류(value) 명시
즉, 위 코드에서는
키: name, age, hobby
밸류: ann, 20, Reading
객체 프로퍼티들은 이 키의 이름에 따라 불리게 됨 -> name, age, hobby로 불리는 것
키 값은 문자열이나 숫자만 가능
또한, 문자열을 사용해도 따옴표는 붙이지 않아도 됨.
다만 띄어쓰기가 필요한 문자열일 경우에 따옴표가 필요
밸류에 들어오는 자료형의 타입은 제한이 없음
-> 문자열, 숫자, 배열, 객체, 함수, 불리언 값 등...
객체 이름 뒤에 .을 붙이고, 접근하고자 하는 프로퍼티의 키 명시
이때,
name이란 변수 중간에 줄이 갈 수도 있는데
이는 타입스크립트와 관련된 경고사항
-> VS Code의 기본 기능이며 무시해도 무관
존재하지 않는 프로퍼티에 접근하려고 하면 오류가 발생하지 않고
대신 undefined가 출력
프로퍼티 + 대괄호 + 대괄호 안에 따옴표로 키 명시
이때 프로퍼티의 키는 반드시 쌍따옴표 안의 문자열로 작성
괄호 표기법도, 존재하지 않는 프로퍼티에 접근하려고 하면 undefined 반환
person 객체에서 변수 property의 값인 hobby 프로퍼티의 밸류인 Reading을 꺼내오게 됨
동적으로 프로퍼티(name, age, hobby)를 변화시키면서 꺼내와야 할 경우 이렇게 사용
아니면 간편한 점 표기법 이용
방식은 무얼 해도 상관 무
이미 있는 프로퍼티를 명시하고, 수정할 값 명시
delete연산자 사용
in 연산자)
name이란 키가 person 안에 들어있는지의 여부가 hasName에 저장
프로퍼티가 in 연산자 다음에 명시된 객체 안에 있냐 없냐
-> 존재하면 true, 존재하지 않으면 false 반환
상수에 저장한 객체
상수에 선언하게 되면, 이미 저장된 값을 바꿀 수 없음
상수 객체도, 이미 상수인 객체를 수정할 수 없음
위처럼 새로 정의(?)하는 건 불가하지만,
위와 같이 기존 프로퍼티의 값을 수정하거나, 삭제가 가능하고,
새 프로퍼티를 추가하는 것도 가능
상수라는 건 엄밀히 말하면 새로운 값을 할당하지 못하는 변수
아예 새로운 값을 할당한 객체를 만드는 건 불가하지만,
이미 저장된 객체 값의 프로퍼티를 수정하는 건 문제 없음
-> 즉, 상수에 객체를 보관해도 프로퍼티 추가, 수정, 삭제 같은 조작은 얼마든지 가능
객체 프로퍼티들 중에 값이 함수인 프로퍼티
위 메서드들은 함수이기 때문에 아래와 같이 호출하는 것도 가능
이런 메서드들은 언제 사용되는가?
객체의 동작을 정의하는 데 사용
-> 함수가 아닌 프로퍼티들이 객체의 정보를 가지고 있다면, 함수 프로퍼티는 객체의 동작을 정의
또한 아래와 같이 배열의 생성과 동시에 값을 할당하는 방식도 있음
또한, 배열 안에는 어떤 타입의 값이든 자유롭게 넣을 수 있음
길이도 한계 없음
각각의 원소에 번호로 접근 가능
다만 인덱스의 번호는 0부터 시작한다는 것을 주의
(인덱스: 배열의 원소 중 몇 번째 원소를 가져오고 싶은지 의미하는 숫자)
이 인덱스 번호로 특정 원소 수정 가능
0번 인덱스의 값을 수정하면 아래와 같이 변경되는 것을 볼 수 있음
전반적으로 아는 내용이지만, 알고 가면 좋을 내용, 그리고 몰랐던 용어들은 추후에 다시 보는 걸로👀