-
320x100
자바스크립트 기본
https://ko.javascript.info/first-steps엄격 모드
- 자바스크립트는 기존 기능을 변경하지 않고 추가만 하는 식으로 호환성 문제를 회피했습니다.
- 그런데 ES5(2009)에서 기존 기능 일부를 변경하게 되었는데요, 혹시나 싶은 문제를 피하기 위해 이 새로운 기능들은 기본적으로 비활성화 상태입니다.
- 새롭게 추가된 기능을 쓰고 싶다면,
use strict
라고 외쳐주세요. 그럼 '엄격 모드'가 됩니다. - 이 주문은 주로 스크립트 최상단에서 외칩니다. 그래야 스크립트 전체가 엄격 모드로 적용되니까요.
- 만약 클래스와 모듈을 사용해 스크립트를 작성했다면 이미 엄격모드가 적용된 거나 다름 없어서 굳이 적지 않아도 됩니다.
기본 연산자와 수학
- %(나머지 연산자): x % b 는 x를 b로 나누고 그 나머지를 정수로 반환합니다.
- **(거듭제곱 연산자): x ** b는 x를 b번 곱한 값을 반환합니다. (2**3 = 8) 단, 이는 ES7에서 추가된 스펙입니다.
- 이항 연산자(+)와 함께 쓰인 피연산자 중 문자열이 있으면 문자열로 변환됩니다.
alert( 2+2+'1' ) //결과: '41'
- 덧셈 연산자(+)가 숫자가 아닌 경우 숫자형으로 변환됩니다.
alert( +"" ); //결과: 0
let a=5; let b=1; alert( +a + +b ); //결과: 6
- ++/--는 피연산자의 앞뒤 어디에도 위치할 수 있습니다. 전위형은 증가/감소 후 새로운 값을 반환하고, 후위형은 증가/감소 전 기존값을 반환합니다.
let counter = 1; let a = ++counter; alert(a); //결과: 2
let counter = 1; let a = counter++; alert(a); //결과: 1
- 따라서 값을 증가시키고 증가한 값을 바로 사용하려면 전위형을, 값을 증가시키되 기존 값을 사용하려면 후위형을 사용합니다.
비교 연산자
- 문자열 비교: JS는 대소문자를 따져 비교합니다. "A"와 "a" 중 "a"가 더 크다고 판단하며, 이는 JS 내부에서 사용되는 인코딩 표인 유니코드에서 소문자가 더 큰 인덱스를 갖고 있기 때문입니다.
- 비교하려는 값의 자료형이 다르면 관대하신 JS는 이들을 숫자형으로 바꿔줍니다.
alert( '2' > 1 ); //결과: true
- null과 undefined는 ===를 사용하면 false, ==를 사용하면 true가 반환됩니다.
null === undefined //결과: false
null == undefined //결과: true
- 만약 산술 연산자나 기타 비교 연산자(<, > 등)을 사용할 경우 숫자형으로 변환되는데, null은 0, undefined는 NaN이 됩니다. 단, 동등 연산자(==)는 피연산자가 null 또는 undefined일 때 형 변환을 하지 않습니다.
null == 0 //결과: false
논리 연산자
- OR (||)
- 인수 중 하나라도 true라면 true를 반환. 그렇지 않다면 false를 반환합니다.
if (1 || 0) {}; //결과: true
- OR 연산자가 여러 개라면 왼쪽부터 시작해 순서대로 평가합니다. 이때, 피연산자를 불린형으로 변환하는데 그 값이 true면 연산을 멈추고 변환 전 원래 값을 반환합니다. 모두 평가한 후에도 false라면 마지막 피연산자를 반환합니다.
alert(null || 0 || 1); //결과: 1 (1은 truthy임)
alert(undefined || null || 0); //결과: 0 (모두 falsy임)
- 인수 중 하나라도 true라면 true를 반환. 그렇지 않다면 false를 반환합니다.
- AND (&&)
- 피연산자 모두가 참일 때 true를 반환. 그렇지 않다면 false를 반환합니다.
if (1 && 0) {}; //결과: false
- AND 연산자가 여러 개라면 왼쪽부터 시작해 순서대로 평가합니다. 이 과정은 OR 연산자와 유사하며, 변환된 값이 false면 연산을 멈추고 변환 전 원래 값을 반환합니다.
alert( 1 && null && 5 ); //결과: null
alert( 1 && 2 && 3 ); //결과: 3
- 피연산자 모두가 참일 때 true를 반환. 그렇지 않다면 false를 반환합니다.
- NOT (!)
- 피연산자를 불린형으로 변환한 뒤 그 값의 역을 반환합니다.
alert ( !true ); //결과: flase
- NOT을 연달아 두 개 사용(!!)하면 값을 불린형으로 변환할 수 있습니다. 이는 내장 함수인 Boolean을 사용한 것과 동일합니다.
alert ( !!"non-empty string" ); //결과: true
alert ( Boolean(null) ); //결과: false
- 피연산자를 불린형으로 변환한 뒤 그 값의 역을 반환합니다.
예제
[1] ` alert( alert(1) || 2 || alert(3) ); ` 의 결과는?
- 답: 얼럿 창엔 1, 2가 차례대로 출력됩니다.
- 먼저 alert(1)을 평가합니다. 이때 첫 번째 얼럿 창에 1이 출력되죠.
- alert() 메서드는 undefined를 반환합니다. 이는 falsy 이므로 OR 연산자는 다음 피연산자를 평가합니다.
- 다음으로 평가되는 2는 truthy이므로 실행이 멈추고 2가 반환됩니다. 반환된 2는 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 2가 출력됩니다.
- 평가가 alert(3)까지 진행되지 않으므로 3은 출력되지 않습니다.
[2] `alert( alert(1) && alert(2) ); `의 결과는?
- 답: 얼럿 창엔 1, undefined가 차례대로 출력됩니다.
- 먼저 alert(1)을 평가합니다. 이때 첫 번째 얼럿 창에 1이 출력되죠.
- alert() 메서드는 undefined를 반환합니다. 이는 falsy 이므로 AND 연산자는 평가를 멈춥니다.
- 반환된 undefined는 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 undefined가 출력됩니다.
[3] `alert( null || 2 && 3 || 4 );`의 결과는? ✔️
- 답: 얼럿 창엔 3이 출력됩니다.
- &&의 우선순위가 높으므로 우선 2 && 3이 실행됩니다. 둘 다 truthy이므로 3이 반환됩니다.
- 먼저 null을 평가합니다. 이는 falsy이므로 OR연산자는 다음 피연산자를 평가합니다.
- 이후 3을 평가합니다. 이는 truthy이므로 OR연산자는 평가를 멈춥니다.
- 반환된 3은 바깥쪽 alert() 메서드의 피연산자가 되어 얼럿 창에 3이 출력됩니다.
null 병합 연산자 '??'
- ES2020(ES11)에 추가된 스펙입니다.
??를 사용하면 여러 피연산자 중 그 값이 '확정된' 변수를 찾을 수 있습니다. (=값이 null 또는 undefined가 아닌 변수)
ex) a ?? b 평가 시, a가 null 또는 undefined가 아니라면 a. 그 외의 경우는 b - 따라서 아래 두 코드는 동일한 기능을 합니다.
[1]let name = ( realName !== null && realName !== undefined ) ? realName : nickName;
[2]let name = realName ?? nickName
으로 줄여서 표현할 수 있습니다. - 이는 || 연산자와 유사하지만 차이점이 있습니다. ||는 첫 번째 truthy의 값을 반환하고, ??는 첫 번째 truthy의 '정의된' 값을 반환합니다.
let height = 0;
let myHeight = height || 180; //결과: 180
let yourHeight = height ?? 180; //결과: 0
- height || 180은 0을 falsy 값으로 판단하여 이를 null이나 undefined와 동일하게 취급합니다. 따라서 첫 번째 truthy는 180이 됩니다.
- 하지만 height ?? 180은 height가 정확하게 null이나 undefined일 때만을 falsy라고 판단합니다. 따라서 첫 번째 truthy는 height이며 여기에 정의된 0이 됩니다.
- 이러한 특징 때문에 0이 할당될 수 있는 변수를 사용할 때는 ??가 적합합니다.
- 현재 JS에서는 안정성 관련 이슈 때문에 ??를 ||나 &&와 함께 사용하지 못하도록 제약이 걸려 있습니다. 단, 괄호로 묶으면 함께 사용할 수 있습니다.
반복문
- while
- 조건이 truhty인 동안 반복문 본문 내용을 반복합니다.
- 반복문 본문이 한 번 실행되는 것을 iteration이라고 부릅니다.
let i = 0; while (i < 3) { alert( i ); // 0, 1, 2가 출력됩니다. i++; }
- do..while
- condition이 본문 다음에 나오는 형태로, 본문이 '최소한 한 번 이상 실행되어야'할 때 사용합니다.
let i = 0; do { alert( i ); // 0, 1, 2가 출력됩니다. i++; } while (i < 3);
- condition이 본문 다음에 나오는 형태로, 본문이 '최소한 한 번 이상 실행되어야'할 때 사용합니다.
- for
- begin; condition; step;으로 이뤄진 반복문입니다.
for (begin; condition; step) { // ... 반복문 본문 ... }
- 세미콜론 `;` 만 남기고 불필요한 내용을 생략할 수도 있습니다.
let i = 0; for (; i < 3; i++) { alert( i ); }
- begin; condition; step;으로 이뤄진 반복문입니다.
- 반복문 빠져나오기
- `break`를 사용하면 반복문을 종료합니다.
- 본문 가운데나 본문 여러 곳에서 조건을 확인해야 하는 경우, '무한 반복문 + break' 조합을 사용하면 좋습니다.
- 여러 개의 중첩 반복문을 빠져나와야 한다면, 단순히 break 선언만으론 부족합니다. 이럴 때는 `{라벨이름}:`을 사용합니다. 반복문 앞에 식별자를 붙이고, 해당 반복문을 종료시킬 수 있습니다.
outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { let input = prompt(`(${i},${j})의 값`, ''); if (!input) break outer; // 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다. } } alert('완료!');
- 다음 반복으로 넘어가기
- `continue`는 전체 반복문을 멈추지 않고, 현재 실행 중인 이터레이션만 종료시킨 뒤 다음 이터레이션으로 넘어가도록 합니다.
- 예를 들어 홀수만 출력시키고 싶은 경우,
for (let i=0; i<10; i++) { if (i % 2) { alert(i); } }
위와 같이 사용할 수 있지만, continue를 쓸 수도 있습니다.
for (let i=0; i<10; i++) { if (i % 2 ==) continue; }
예제
[1] 아래 코드의 실행 결과는?
let i = 0; while (i++ < 5) alert( i );
- 답: 얼럿 창에 1,2,3,4,5가 출력됩니다.
- ++가 뒤에 나오는 경우는 값을 증가하되 기존값을 반환합니다. 따라서 비교는 (0<5)가 되며 이는 참입니다. 한편, alert()는 조건문과 별개이므로 이미 증가해서 넘어온 i를 받고 1을 출력합니다.
[2] 아래 두 코드의 실행 결과는 동일할까요?
//1 for (let i = 0; i < 5; i++) alert( i ); //2 for (let i = 0; i < 5; ++i) alert( i );
- 답: 동일하게 0,1,2,3,4를 출력합니다.
- 왜냐하면 i++나 ++i는 조건 확인과 별개의 구문이기 때문입니다. for문은 그저 증가된 i를 조건 확인에 사용할 뿐입니다. 따라서 증가 연산자가 반환한 값은 어디에도 쓰이지 않습니다.
[3] 사용자가 100보다 큰 숫자를 입력할 때까지 프롬프트 창을 띄우고, 아무것도 입력하지 않거나 취소한 경우 프롬프트 창을 취소하는 코드를 작성해 보세요.
- 답:
let num; do { num = prompt("100을 초과하는 숫자를 입력해주세요.", 0); } while (num <= 100 && num
- num이 null인 경우 num <= 100은 true가 되므로 두 번째 조건이 없으면 취소 버튼을 눌러도 반복문이 계속해서 실행됩니다. 따라서 위 두 조건을 모두 확인해야 합니다.
함수
- 매개변수
- 매개변수와 인자는 다릅니다!
- (1) 매개변수/파라미터(parameter): 함수를 실행하기 위해 필요하다고 지정하는 값
👉 입장을 위해 마련해두는 의자 - (2) 인수/인자(arguments): 함수를 호출할 때 매개변수로 넘기는 값
👉 실제로 입장한 사람
- (1) 매개변수/파라미터(parameter): 함수를 실행하기 위해 필요하다고 지정하는 값
- 함수는 복사된 값을 사용하기 때문에 외부 변수에 영향을 주지 않습니다. 즉, 함수에 전달된 매개변수는 복사된 후 함수의 지역변수가 됩니다.
- 함수는 외부 변수에 접근할 수 있지만, 바깥에서 함수 내부의 지역변수에는 접근할 수 있습니다.
let num = 22; add = (x, y) => { return x + y; } //(x,y)는 매개변수 add(num,2); //(num,2)는 인수
- 매개변수에 값을 전달하지 않으면 그 값은 `undefined`가 됩니다.
- 함수를 정의할 때 매개 변수 오른쪽에 `=`을 붙여 기본값을 설정할 수 있습니다.
someFunc = () => { return 'hello' }; showMsg = (name, msg = someFunc()) => { alert(name+' says '+msg); }; showMsg('nana'); //결과: 'nana says hello'
- 또는 선언부 대신, 함수 실행 도중에 기본값을 설정할 수도 있습니다.
showMsg = (text) => { text = text || 'Hey!'; ... }
- 매개변수와 인자는 다릅니다!
- 리턴
- 함수는 무조건 뭔가를 돌려줍니다. (네! 항상 무언가를 싸요! 💩)
- return문이 없거나 return 지시자만 있는 경우라도 undefined를 반환합니다.
(즉, return; === return undefined;인 거죠)
- 함수 이름짓기
- 함수 이름은 대개 동사로 짓습니다. 함수 이름만 보고도 함수가 어떤 기능을 하는지 알 수 있어야 합니다.
- get: 값 반환
- calc: 계산
- create: 생성
- check: 확인 후 불린값 반환
- show: 무언가를 표시함
- 함수는 동작 하나만 담당해야 합니다. 즉, 이름에 언급된 동작만 수행해야 합니다.
- ex) getAge() 함수는 나이를 얻어오기만 해야 합니다. alert()로 출력해주는 동작은 다른 함수가 해야 합니다.
- ex) createForm() 함수는 form 생성 후 반환하기만 해야 합니다. form을 문서에 출력하는 동작은 다른 함수가 해야 합니다.
- 함수는 주석이 없어도 그 존재 자체가 무슨 역할을 하는지 설명할 수 있어야 합니다. 코드를 분리해 작성하면 더 나은 코드 구조가 됩니다.
- 함수 이름은 대개 동사로 짓습니다. 함수 이름만 보고도 함수가 어떤 기능을 하는지 알 수 있어야 합니다.
- 함수 표현식 vs. 함수 선언문
- 함수 선언문은 독자적인 구문 형태로 존재합니다.
function sum(a, b) { return a + b; }
- 함수 표현식은 구문 구성(syntax construct) 내부에 생성됩니다. 이때 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성합니다.
let sum = function(a, b) { return a + b; };
- 따라서 함수 선언문은 정의 전에 호출할 수 있습니다. 왜냐면 JS는 스크립트를 실행하기 전, 전역에 선언된 함수 선언문을 찾아 해당 함수를 생성하기 때문입니다.
- 또한 '엄격 모드'를 사용 중이라면, 함수 선언문으로 선언된 코드는 블록 내에서만 유효하고, 블록 밖(중괄호 밖)에서는 호출할 수 없습니다.
- 함수 선언문은 독자적인 구문 형태로 존재합니다.
+++
prompt()
- 확인을 누르면 해당 값(문자열)을 반환
- 취소를 누르면 null을 반환
- 아무 것도 입력하지 않으면 빈 문자열을 반환
confirm()
- 확인을 누르면 true를 반환
- 취소를 누르면 false를 반환728x90'🐿 > JS' 카테고리의 다른 글
CRA(create-react-app) 환경에서 절대경로 / 전역 Sass 사용하기 (0) 2022.03.16 2021년 회고 (0) 2021.12.29 댓글 0