32기 솝트 웹파트 자바스크립트 스터디 1주차에서 공부한 내용을 정리합니다. (출처 : 모던자바스크립트 튜토리얼 2.10,2.11,2.16,2.17)
if문에서는 괄호 안의 표현식을 평가하고 그 결과를 불린값으로 반환한다.
숫자 0, 빈 문자열"", null, undefined, NaN
은 형변환 규칙에 따라 불린형으로 변환 시 모두 false가 된다.
이러한 값을 falsy한 값(거짓 같은 값)이라고 부르고, 이 외의 값은 불린형으로 변환 시 모두 true가 되므로 truthy한 값 (참 같은) 값이라고 부른다.
if (0) { // 0은 falsy로, 코드 블록이 절대 실행되지 않는다.
...
}
if (1) { // 1은 truthy로, 코드 블록이 항상 실행된다.
...
}
조건부 연산자는 피연산자가 3개로 삼항 연산자
라고 부르기도 한다.
자바스크립트에서 피연산자를 3개나 받는 연산자는 삼항 연산자가 유일하다고 한다.
let result = condition ? value1 : value2;
// let myLevel= (score > 50) ? 2 : 1;
condition이 truthy라면, value1이, 그렇지 않다면 value2가 반환된다.
condition에 괄호가 있으나 없으나 큰 차이는 없지만, 코드의 가독성 향상을 위해 괄호를 사용할 것을 권장한다.
물음표 연산자 ?를 여러개 연결해서 if~else와 같이 복수의 조건을 처리할 수 있다.
let message = (age < 3) ? '아기야 안녕?' :
(age < 18) ? '안녕!' :
(age < 100) ? '환영합니다!' :
'나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';
처음 이 코드를 보았을 때 해석이 잘 안되었는데 결국은 (age < 3)
, (age < 18)
, (age < 100)
를 순차적으로 검사하는 코드이다.
해당 코드는 if~else를 이용해 다음과 같이 바꿀 수 있다.
if (age < 3) {
message = '아기야 안녕?';
} else if (age < 18) {
message = '안녕!';
} else if (age < 100) {
message = '환영합니다!';
} else {
message = '나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';
}
삼항 연산자는 조건에 따라 반환값을 달리하려는 목적으로 만들어졌다.
그러면 다음과 같이 코드를 작성한다면 어떨까?
let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');
(company == 'Netscape') ?
alert('정답입니다!') : alert('오답입니다!');
개발자 입장에서는 if문을 사용할 때보다 코드 길이가 짧아져 매력적일 수 있으나, 삼항 연산자의 목적에 부합하지 않아 오히려 가독성을 해칠 수 있다.
따라서 실행되는 표현식을 처리할 때에는 다음과 같이 적어주는 것이 좋다.
let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');
if (company == 'Netscape') {
alert('정답입니다!');
} else {
alert('오답입니다!');
}
자바스크립트에는 ||
, &&
, !
이렇게 3개의 논리 연산자가 있다.
OR 연산자는 다음 순서에 따라 연산을 수행한다.
result = value1 || value2 || value3;
여기서 보면 반환 값이 boolean으로 변환된 값이 아니라 원래 값이다.
다음과 같은 식을 실행하면 어떠한 결과가 나올까?
alert( undefined || null || 0 );
undefined, null, 0 은 모두 falsy한 값이기 때문에 마지막 0이 alert 창에 뜨게 될 것이다.
✅ 다음과 같은 OR 연산자의 특성을 여러 용도로 사용할 수 있다.
1. 변수 또는 표현식으로 구성된 목록에서 첫번쨰 truthy 얻기
말이 어려우니 예시를 바로 보자.
let firstName = "";
let lastName = "";
let nickName = "바이올렛";
alert( firstName || lastName || nickName || "익명"); //바이올렛
순차적으로 값을 boolean으로 변환한 결과 nickname에서 가장 먼저 true가 나오기 때문에 반환 값은 "바이올렛"이 된다.
실명, 닉네임, 익명을 모두 활용하는 서비스에서 유용하게 쓸 수 있을 것 같다.
2. 단락 평가
왼쪽 조건이 falsy일 때만 명령어를 실행하고자 할 때 자주 쓰인다.
true || alert("not printed");
false || alert("printed");
첫번째 줄의 경우, true인 경우 평가를 멈추기 떄문에 alert가 실행되지 않는다.
두번째 줄의 경우, alert("print")에서 연산이 멈추기 때문에 alert창을 볼 수 있다.
&&는 다음과 같은 순서로 작동한다.
OR과 비슷한 알고리즘으로 작동한다는 것을 알 수 있다.
다음과 같은 속성을 사용하면 OR과 비슷하게 처음으로 falsy가 나오는 값을 확인할 수 있다.
alert( 1 && 5 ); // 5
alert( 1 && 2 && null && 3 ); // null
a && b || c && d
는 (a && b) || (c && d)
과 같이 동작한다. // ✅ 조건, 그리고 해당 조건에 대한 실행의 관계가 잘 보이지 않는다.
(x > 0) && alert( '0보다 큽니다!' );
// ✅ 가독성이 훨씬 개선되었다.
if (x > 0) alert( '0보다 큽니다!' );
!의 작동 원리는 다음과 같다.
result = !value;
✅ !을 두개 연달아서 !!와 같이 사용하면 값을 불린형으로 변환할 수 있다.
alert( !!"non-empty string" ); // true
alert( !!null ); // false
첫번째 !이 값을 boolean형으로 만들어 역으로 만들고, 두번째 !는 첫번째 !이 반환한 값의 역을 반환한다.
결국 원래 값의 boolean형을 얻을 수 있는 것이다.
✅ !!는 내장함수 Boolean으로 대체할 수도 있다.
alert( Boolean("non-empty string") ); // true
자바스크립트에서는 함수를 특별한 동작을 하는 구조가 아닌, 특별한 종류의 값으로 취급한다.
(일반적인 값이 데이터를 나타낸다면, 함수는 동작
을 나타내는 값이다.)
이를 보여주는 것이 함수 표현식이다.
let sayHi = function() {
alert( "Hello" );
};
다음과 같이 변수에 값을 할당하는 것처럼 변수에 함수를 할당할 수 있다.
즉, 함수를 값으로 취급하는 것이다.
따라서 값에 할 수 있는 일을 함수에도 할 수 있다.
가장 대표적인 것이 변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당하는 것이다.
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
//✅ let func = sayHi();이 아닌 것에 유의하자. sayHi()와 같이 쓰면 함수 그 자체가 아니라 반환값이 변수에 저장된다.
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행
sayHi(); // Hello
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 해당 함수를 나중에 호출
하는 것이 콜백함수의 개념이다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
ask("동의하십니까?", showOk, showCancel);
ask 함수의 인수로 들어간 showOk와 showCancel이 콜백함수이다.
다음과 같이 함수 표현식을 사용하면 코드 길이를 짧게 만들 수 있다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
ask 안에 함수가 선언되어 있는데, 이렇게 이름 없이 선언한 함수를 익명 함수
라고 한다.
익명 함수는 변수에 할당된 것이 아니기 때문에 ask 바깥에서는 접근 할 수 없다.
1. 문법
// ✅ 함수 표현식
let sum = function(a, b) {
return a + b;
};
// ✅ 함수 선언문
function sum(a, b) {
return a + b;
}
2. 함수 생성 시기
함수 표현식 : 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성한다.
함수 선언문 : 함수 선언문이 정의되기 전에도 호출할 수 있다.
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
함수가 선언되기도 전에 사용했는데 alert창이 제대로 출력되는 것이 이상하다고 느낄 수도 있지만 함수 선언문, sayHi는 스크립트 실행 준비 단계에서 생성되기 때문에, 스크립트 내 어디에서든 접근할 수 있다.
자바스크립트의 내부 알고리즘에서 스크립트를 실행하기 전 준비단계에서 전역에 선언된 함수 선언문을 찾고, 해당 함수를 생성한다.
즉, 스크립트가 진짜 실행되기 전 "초기화 단계"에서 함수 선언 방식으로 정의한 함수가 먼저 생성되는 것이다.
(나는 자바스크립트 내부 알고리즘이 스크립트를 먼저 쓱 훑은 후 함수 선언식만 골라서 먼저 생성한다는 말로 이해했다.)
sayHi("John"); // error!
let sayHi = function(name) {
alert( `Hello, ${name}` );
};
하지만 함수 표현식으로 선언한 sayHi는 실행 흐름이 표현식에 다다랐을 때 만들어지기 때문에 함수 선언 전에 실행할 수 없다.
3. 스코프
함수 선언문 : 엄격모드(use strict
로 엄격모드를 활성화해야만 ES6 변경 사항의 대부분을 적용할 수 있다.)에서 함수 선언문이 코드 블록 내에 위치하면 블록 내 어디서든 함수를 접근할 수 있다. 하지만, 블록 밖에서는 접근할 수 없다.
let age = 16;
if (age < 18) {
welcome(); // 함수 선언문은 함수가 선언된 블록 내 어디서든 유효하다
function welcome() {
alert("안녕!");
}
welcome(); // 함수 선언문은 함수가 선언된 블록 내 어디서든 유효하다
} else {
function welcome() {
alert("안녕하세요!");
}
}
welcome(); // Error: welcome is not defined
다음과 같이 함수 선언문을 사용하면 코드 블록 밖에서 사용시 에러를 발생시키지만, 함수가 위치한 블록 내에서는 함수 선언 전과 후 언제든 접근할 수 있다.
함수 표현식 : 함수가 위치한 코드 블록 밖에서 사용이 가능하다.
let age = prompt("나이를 알려주세요.", 18);
if (age === 18) {
welcome(); //✅ 함수 표현식이기 때문에 선언 전에 접근할 수 없다. (에러 발생)
welcome = function() {
alert("안녕!");
};
}
welcome(); //안녕하세요!
✅ 자바스크립트에서는 함수 이름 옆에 괄호를 써주지 않으면 실행되지 않는다.
function sayHi() {
alert( "Hello" );
}
alert( sayHi );
위 코드의 실행결과는 다음과 같다.
괄호를 적어주지 않은 함수가 소스 코드가 문자형으로 바뀌어 값으로써 출력이 된 것이다.
✅ 함수는 값이라면서 왜 세미 콜론은 붙지 않나요?
이유는 중괄호로 만든 코드 블록의 끝에는 세미 콜론이 없어도 되기
때문입니다.
화살표 함수는=> 왼쪽에 있는 인수를 이용해 => 오른쪽에 있는 표현식을 평가
하는 방식입니다.
만약 오른쪽에 있는 표현식이 한 줄이라면 따로 return을 명시해주지 않아도 되지만, 여러 줄이라면 중괄호로 표현식을 감싸고 return을 명시해야합니다.
let sum = (a, b) => a + b;
// 한 줄뿐이라 return이 필요하지 않다.
let sum = (a, b) => {
let result = a + b;
return result; // 중괄호를 사용했다면, return 지시자로 결괏값을 반환해주어야 한다.
};
덕분에 조건 처리 및 논리 연산자, 함수에 대해 헷갈렸던 부분 다시 한번 짚고 넘어갈 수 있었어요!
특히 개념 하나 하나마다 적절한 예시를 들어주셔서 더 잘 들어왔던 것 같네용 좋은 글 감사합니다~🌞🌞