앞으로 내용을 학습하기 위해 필수로 기억해야 할 키워드들입니다.
값: 표현식이 평가되어 생성된 결과
리터럴: 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법
표현식: 값으로 평가될 수 있는 문
문: 프로그램을 구성하는 기본 단위이자 최소 실행 단위
여러 토큰으로 구성되며 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 토큰이라 한다.
ASI: 자바스크립트에서는 기본적으로 문의 종료라고 생각되는 부분에 세미콜론을 자동으로 삽입해 줍니다.
하지만 개발자가 예측한 결과와 실제 자동으로 삽입된 세미콜론의 위치가 다를 수 있기에 세미콜론을 직접 삽입하는 것을 권장합니다.
이는 논쟁의 요소로 관련 부분에 대해 궁금하다면 해당 글을 참고해주세요.
크롬 개발자 도구에서는 표현식이 아닌 문을 실행하면 undefined를 반환하고, 표현식인 문을 실행하면 평가된 값을 반환합니다.
자바스크립트의 타입은 6개의 원시 타입과 1개의 객체 타입으로 구분된다.
템플릿 리터럴은 멀티라인 문자열, 표현식 삽입, 태그드 템플릿 등의 문자열 처리 기능을 지원하며 백틱으로 감싸서 표현합니다.
런타임 시에 일반 문자열로 변환되며, 지원되는 기능 중 표현식 삽입은 아래와 같이 사용합니다.
var first = 'Jae-hun';
var last = 'Kim';
console.log(`My name is ${first} ${last}.`); // My name is Jae-hun Kim.
숫자 타입에는 세 가지 특별한 값이 있습니다.
- Infinity: 양의 무한대
- -Infinity: 음의 무한대
- NaN: 산술 연산 불가(not-a-number)
자바스크립트에서는 변수가 선언과 동시에 정의가 이뤄지지만 구분이 엄격한 언어에서는 선언 후 실제로 메모리 주소를 할당하는가?(정의)로 구분됩니다. 책에서는 ECMAScript 사양을 따라 변수는 선언, 함수는 정의라고 표현합니다.
심벌 타입은 아래와 같이 사용합니다.
var key = Symbol('key');
console.log(typeof key); // symbol
var obj = {};
obj[key] = 'value';
console.log(obj[key]); // value
정적 타입: 명시적 타입 선언(변수를 선언할 때 타입을 사전에 함께 선언)을 하며, 컴파일 시점에 타입 체크를 하고 통과하지 못 할 시 프로그램의 실행 자체를 막습니다.
동적 타입: 자바스크립트가 이에 해당하는데 변수의 선언이 아닌 할당으로 타입이 결졍되는 데 이를 타입 추론이라고 합니다.
자바스크립트에서는 typeof 연산자로 저장된 값의 타입을 확인할 수 있습니다.
책에서 설명하는 변수를 사용할 때 주의사항
1. 변수는 꼭 필요한 경우에 제한적으로 사용한다. 변수 값은 재할당에 의해 언제든지 변경될 수 있다. 이로 인해 동적 타입 언어인 자바스크립트는 타입을 잘못 예측해 오류가 발생할 가능성이 크다. 변수의 개수가 많으면 많을수록 오류가 발생할 확률도 높아진다. 따라서 변수의 무분별한 남발은 금물이며, 필요한 만큼 최소한으로 유지하도록 주의해야 한다.
2. 변수의 유효 범위(스코프)는 최대한 좁게 만들어 변수의 부작용을 억제해야 한다. 변수의 유효 범위가 넓으면 넓을수록 변수로 인해 오류가 발생할 확률이 높아진다.
3. 전역 변수는 최대한 사용하지 않는다. 어디서든지 참조/변경 가능한 전역 변수는 의도치 않게 값이 변경될 가능성이 높고 다른 코드에 영향을 줄 가능성도 높다. 따라서 전역 변수는 프로그램의 복잡성을 증가시키고 처리 흐름을 추적하기 어렵게 만들고, 오류가 발생할 경우 오류의 원인을 특정하기 어렵게 만든다.
4. 변수보다는 상수를 사용해 값의 변경을 억제한다.
5. 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다. 변수 이름뿐 아니라 모든 식별자(변수, 함수, 클래스 이름 등)는 존재 이유를 파악할 수 있는 적절한 이름으로 지어야 한다. 특히 식별자의 유효 범위가 넓을수록 명확한 이름을 명명하도록 노력하자. 개발자의 의도를 나타내는 명확한 네이밍은 코드를 이해하기 쉽게 만들고, 이는 협업과 생산성 향상에 도움을 준다. 다시 말하지만 변수 이름은 첫아이 이름을 짓듯이 심사숙고해서 지어야 한다.
연산자는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수 연산 등을 수행해 하나의 값을 만들며, 이 때 연산의 대상을 피연산자라고 합니다.
산술 연산자는 피연산자를 대상으로 수학적 계산을 수행해 새로운 숫자 값을 만들며, 연산이 불가한 경우 NaN을 반환합니다.
피연산자의 개수에 따라 단항, 이항, 삼항 연산자로 구분하며, 삼항 연산자는 삼항 조건 연산자가 유일합니다.
단항 연산자 중 증가/감소 연산자의 경우 위치에 따라 의미가 달라질 수 있습니다.
var x = 5, result;
// 선할당 후증가(postfix increment)
result = x++;
console.log(result, x); // 5 6
// 선증가 후할당(prefix increment)
result = ++x;
console.log(result, x); // 7 7
// 선할당 후감소(postfix decrement)
result = x--;
console.log(result, x); // 7 6
// 선감소 후할당(prefix decrement)
result = --x;
console.log(result, x); // 5 5
var x = '1';
// 문자열 -> 숫자
console.log(+x); // 1
// 불리언 -> 숫자
x = true;
console.log(+x); // 1
x = false;
console.log(+x); // 0
// 숫자로 변환할 수 없는 문자열
x = 'Hello';
console.log(+x); // NaN
단항 연산자 -는 원래 값에서 부호를 반전한 값을 반환하는데, 값이 숫자 타입이 아닌 경우 단항 연산자 +와 동일하게 동작한 결과에서 부호가 반전된 값을 반환합니다.
피연산자 하나 이상이 문자열인 경우 + 연산자는 문자열 연결 연산자로 동작합니다.
또다른 피연산자가 숫자 타입인 경우 문자열 타입으로 강제 변환한 후 연산을 수행하는데 이를 암묵적 타입 변환 또는 타입 강제 변환이라 합니다.
// 문자열 연결 연산자
'1' + 2; // -> '12'
1 + '2'; // -> '12'
// 산술 연산자
1 + 2; // -> 3
==
)와 일치 비교(===
)로 구분되는데 전자는 값이 같은지만 비교하며, 후자는 타입까지 일치하는지 비교합니다.// 동등 비교
5 == 5; // -> true
5 == '5'; // -> true
// 일치 비교
5 === 5; // -> true
5 === '5'; // -> false
// 예외로 NaN은 자신과 일치하지 않는 유일한 값
// NaN인지 조사하려면 빌트인 함수를 이용
NaN === NaN; // -> false
isNaN(NaN); // -> true
isNaN(10); // -> false
// 숫자 0의 경우 부호와 관계 없이 동등/일치 비교 모두에서 true를 반환
0 == -0; // -> true
0 === -0; // -> true
// ES6에서 도입된 Object.is 메서드를 이용하면 보다 정확한 비교 가능
Object.is(-0, +0); // -> false
Object.is(NaN, NaN); // -> true
var x = 2;
var result = x % 2 ? '홀수' : '짝수';
console.log(result); // 짝수
typeof 연산자를 통해 피연산자의 데이터 타입을 문자열로 반환할 수 있지만 null의 경우 object가 반환되는 버그가 있습니다. 기존 코드에 영향을 줄 수 있어 수정되지 못 하고 있습니다.
따라서 null 체크는 일치 연산자를 이용
참조할 수 없는 식별자(선언하지 않은 식별자 등)를 참조할 시 undefined를 반환합니다.
typeof undeclared; // -> undefined
2 ** 2; // -> 4
2 ** 2.5; // -> 5.65685424949238
2 ** 0; // -> 1
2 ** -2; // -> 0.25
Math.pow(2, 2); // -> 4
Math.pow(2, 2.5); // -> 5.65685424949238
Math.pow(2, 0); // -> 1
Math.pow(2, -2); // -> 0.25
-5 ** 2; // SyntaxError
(-5) ** 2; // -> 25
.project-card {
width: calc(50% - 20px);
}
.project-card img {
--widthImg: calc(100% - 40px);
width: var(--widthImg);
height: calc(var(--widthImg) / 75%);
}