조건에 따라 어떤 값을 결정해야 함 -> 삼항 연산자 표현식
이 좋음
조건에 따라 수행해야할 문이 여러개 -> if~else 문
이 가독성 면에서 좋음
// 삼항 연산자로 홀짝 판별
let number = 2;
let result = x % 2 ? "홀수" : "짝수"; // 판별식이 0이면 타입 캐스팅으로 false로 판단됨
console.log(result); // "짝수"
ES7에서 도입됨
// 전에는 Math.pow(base, exponent) 메서드를 사용했음
Math.pow(2, 2); // 4
Math.pow(2, -2); // 0.25
Math.pow(-5, 2); // 25
2 ** 2; // 4
2 ** -2; // 0.25
(-5) ** 2; // 25 음수 거듭제곱시 밑수에 괄호 쓰기 !
표현식 평가 중 결과가 확정되면 평가를 멈추고 결과를 결정하는 피연산자
를 타입 변환 없이 그대로 반환하는 것
대부분의 프로그래밍 언어는 논리 연산을 단축평가로 수행
단축 평가 표현식 | 평가 결과 |
---|---|
true || anything | true |
false || anything | anything |
true && anything | anything |
false && anything | false |
// 논리 연산자 단축 평가
// 논리합(||) 연산
"Cat" || "Dog"; // "Cat" - 첫번째 피연산자가 논리 연산 결과 결정
"Cat" || false; // "Cat"
false || "Dog"; // "Dog" - false를 만날 경우 나머지도 평가
// 논리곱(&&) 연산
"Cat" && "Dog"; // "Dog" - 두번째 피연산자가 논리 연산 결과 결정
"Cat" && false; // "false"
false && "Dog"; // "false" - false를 만날 경우 나머지 평가x
▫ 사용 사례
// ▫ if문 대체 - 값 할당 시 깔끔함
let done = true;
let message = "";
// 💩 조건문으로 값 할당
if (done) message = "값";
// 👍 논리 연산자(논리곱)으로 값 할당
message = done && "값";
// ▫ 함수 매개변수에 기본값을 설정할 때
// 함수를 호출할 때 인수를 전달하지 않으면 매개변수에는 undefined 가 할당됨
// 💩 인수를 전달하지 않을 경우
function getHeight(h) {
return h;
}
getHeight(); // undefined
// 🔺 단축 평가를 사용한 매개변수의 기본값 설정
function getHeight(h) {
h = h || 100;
return h;
}
getHeight(); // 100
//👍 ES11의 null 병합 연산자(??)nullish coalescing oprerator를 통해 더 정확히 매개변수 기본값 설정 가능
// elem이 null or undefined 일 때만 우항의 피연산자 반환, 이를 제외한 '', 0 등의 falsy 값이면 좌항의 피연산자 반환
function getHeight(h) {
h = h ?? 100;
return h;
}
getHeight(0); // 0 논리합 사용했으면 잘못된 값(100) 나왔음
// 👍 Es6의 매개변수 default parameter 설정
function getHeight(h = 100) {
return h;
}
getHeight(); // 100
// ▫ 변수가 객체를 참조하는지 확인 후 프로퍼티에 접근하려 할 때
// 변수가 객체가 아닌 null 이나 undefined를 참조하는 경우, 객체의 프로퍼티에 접근시 TypeError가 발생 -> 프로그램 강제 종료
// 💩
let elem = null;
let value = elem.value; // TypeError: Cannot read property 'value' of null
// 🔺
// elem이 "Falsy 값"이면 elem 값으로 평가
// elem이 "Truthy 값"이면 elem.value 로 평가
let elem = null;
let value = elem && elem.value; // null
//👍 ES11의 optional chaining 연산자(?.)를 통해 더 정확히 null, undefined인지 확인 가능
// elem이 null or undefined 일 때만 undefined 반환, 이를 제외한 '', 0 등의 falsy 값이면 우항의 프로퍼티를 참조함
let str = '';
let length = str?.length;
console.log(length); // 0 논리곱 사용했으면 잘못된 값(undefined) 나왔음
논리합,논리곱은 falsy값에 초점을 둬 "", 0을 처리할 때 예상치 못하게 동작할 수 있기 때문에 undefined나 null을 정확하게 처리하려면 논리합보다
null 병합 연산자
, 논리곱보다옵셔널 체이닝 연산자
를 지향해야 함
조건에 따라 코드블록을 실행(조건문)하거나 반복실행(반복문)할 때 사용
코드의 실행 흐름을 인위적으로 제어해 순차적으로 진행되는 직관적인 코드의 흐름에 혼란을 줘 가독성을 해칠 수 있음
forEach(), map(), filter(), reduce() 같은 고차 함수
를 사용한 함수형 프로그래밍 기법
에서는 제어문의 사용을 억제하여 복잡성을 해결하려 함
주어진 표현식을 평가해 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮김
// 윤년(leaf year) 판별
let year = 2000; // 2000년은 윤년 -> 2월은 29일까지
let month = 2;
let days = 0;
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
// 윤년 계산을 올바르게 수행
days = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) ? 29 : 28;
break;
default:
console.log("Invalid month");
}
console.log(days); // 29
else if 여러개 써야하면 switch 쓰는 게 나음
while 문 = 반복 횟수가 불명확할 때 주로 사용
for 문 = 반복 횟수가 명확할 때 주로 사용
js에는 반복문을 대체할 수 있는 다양한 기능이 있음
// for 문 무한루프
// 초기식 , 조건식 , 증감식 을 아무것도 작성하지 않을 경우 while(true) 와 같음
for( ; ; ) { ... }
특정 코드 블록(레이블 블록문, 반복문 ...)을 탈출할 때 사용
/*
레이블 문(label statement) : "식별자"가 붙은 문, 주로 프로그램 실행 순서를 제어하는 데 사용됨
+ 레이블 블록 문을 탈출하려면 break 문에 해당 레이블 식별자를 지정해야함
*/
// 레이블이 있는 블록문
foo: {
console.log(1);
break foo; // foo 레이블 블록문을 탈출
console.log(2); // 이 코드는 실행되지 않음
}
레이블 문은 중첩된 for 문 외부로 탈출 할 때 유용하지만 그 외에는 일반적으로 권장하지 않음
레이블 문 사용시 → 프로그램의 흐름이 복잡해져서 가독성이 나빠지고 오류를 발생시킬 가능성 up (존재만 알자)
반복문의 코드 실행을 현 시점에서 중지 후, 반복문의 증감식으로 흐름을 이동시킴_break문과 달리 반복문을 탈출하진 않음
// if문 내에서 실행해야 여러 코드 있음, continue 문을 사용하지 않았을 경우 -> 중첩 구조가 됨
var arr = [1, 2, 3, 4, 5];
var target = 3;
var count = 0;
for (var i = 0; i < arr.length; i++) {
// arr[i] 가 target 이하라면 count 증감
if (arr[i] <= target) {
count++;
// code...
// code...
// code...
}
}
// continue 문을 사용한 경우 -> depth가 하나 줄어듦
for (var i = 0; i < arr.length; i++) {
// arr[i] 가 target 초과이면 count증감하지 않고 반복문의 증감식으로 흐름이 이동됨
if (arr[i] > target) continue;
count++;
// code...
// code...
// code...
}