모던 웹을 위한 JavaScript jQuery 입문 (3판) - 1
윤인성 저 모던 웹을 위한 JavaScript jQuery 입문 (3판) 내용으로
중요하다고 생각되는 부분을 메모한 내용이다.
값을 만들어내는 간단한 코드를 '표현식'이라고 부름.
더하기 연산자를 제외한 사칙 연산자는 문자열을 숫자로 자동 변환하여 계산한다.
console.log('52 + 273') // 52 + 273
console.log(52 + 273) // 325
console.log('52' + 273) // 52273
console.log('52' + '273') // 52273
console.log('52 * 273') // 52 * 273
console.log('52' * 273) // 14196
console.log('52' * '273') // 14196
console.log('52' * 'string') // NaN (Not A Number)
0, NaN, ''(빈 문자열), null, undefined 모두 false로 취급.
템플릿 문자열은 `` 로 감싸고 문자열 내부 표현식은 ${} 로 감싼다.
// 표현식 273 + 52의 값은 325 입니다.
console.log(`표현식 273 + 52의 값은 ${52 + 273} 입니다.`);
상수는 변할 가능성이 없으므로 '변한다'라는 속성과 관련된 처리가 필요 없다.
처리해야 할 것이 줄어들기 때문에 성능이 향상된다.
키워드 | 구분 | 선언 위치 | 재선언 |
var | 변수 | 전역 스코프 | 가능 |
let | 변수 | 해당 스코프 | 불가능 |
const | 상수 | 해당 스코프 | 불가능 |
var 키워드는 전역에서 사용되므로 메모리 회수가 어렵고
재선언이 가능하여 코드를 이해하기 어렵게 만든다. 사용을 지양하자.
비동기 함수에서 var 키워드의 문제점을 살펴보려고 한다.
n 초 후에 n 을 출력하는 코드를 아래와 같이 작성했다.
/* 코드 2-59 */
for (var i=0; i<3; i++) {
setTimeout(() => {
console.log(i);
}, 1000 * i);
}
결과는?

4가 3번 출력되었다. 3초 후면 var 값 자체가 바뀌어있기 때문에 그렇다.
또한 i++로 후행 연산에 의해 i가 4로 변경된 것을 알 수 있다.
의도한 대로 결과가 나오려면 var 대신 let을 사용하면 된다.
/* 코드 2-61 */
for (let i=1; i<=3; i++) {
setTimeout(() => {
console.log(i);
}, 1000 * i);
}

논리항 연산자를 사용한 짧은 조건문
(<bool 표현식>) || (<bool 표현식이 거짓일 때 실행할 문장>)
(<bool 표현식>) && (<bool 표현식이 참일 때 실행할 문장>)
for in vs for of
const numbers = [1,2,3,4,5]
for (let index in numbers) {
console.log(`${index} => ${numbers[index]}`)
}
for (let element of numbers) {
console.log(element)
}
변수명에서 알 수 있듯이 for in 구문에서는 index 값이 넘어오고
for of 구문에서는 배열의 요소 값이 넘어온다.
이름이 있는 함수를 '선언적 함수', 이름이 없는 함수를 '익명 함수' 라고 부른다.
선언적 함수와 익명 함수의 가장 큰 차이점은 브라우저가 코드를 읽는 시점이다.
웹 브라우저는 script 태그 내의 내용을 한 줄씩 읽기 전에 선언적 함수부터 읽는다.
/* 코드 5-6 */
<script>
함수();
var 함수 = function() { alet('함수 A'); };
var 함수 = function() { alet('함수 B'); };
</script>

/* 코드 5-7 */
<script>
함수();
function 함수() { alert('함수 A'); }
function 함수() { alert('함수 B'); }
</script>

선언적 함수는 브라우저가 먼저 알고 있기 때문에 호출이 가능하지만
익명 함수는 함수에 대한 정보가 없어서 오류가 발생한다.
자바스크립트는 함수를 호출할 때 원래 매개변수 개수보다 많거나 적은 매개변수를 사용하는 것을 허용한다. (알아서 무시)
자바스크립트의 모든 함수 내부에 arguments 변수가 있다.
함수 내부에 함수를 선언할 수 있다 => 내부 함수
함수를 변수에 대입할 수 있다. => 함수의 매개변수로 함수를 전달할 수 있다.
함수의 리턴 값으로 함수를 사용할 수 있다. => 왜? 클로저 때문에.
클로저?
크롤저에 대한 정의가 다양하기 때문에 정의보다는 어떠한 것인지 감을 잡기 위해 예제를 살펴본다.
function test(name) {
var output = 'Hello ' + name + ' .. !';
}
alert(output);
위의 코드에서 output은 지역 변수이므로 test 함수 블럭을 벗어난 곳에서는 사용할 수 없다.
function test(name) {
var output = 'Hello ' + name + ' ..!';
return function() {
alert(output);
}
}
var test_1 = test('Web');
var test_2 = test('JavaScript');
test_1();
test_2();
위의 코드에서도 마찬가지로 output은 지역변수이지만 test 함수의 리턴값으로 사용되면서
다른 곳에서 호출될 가능성이 있기 때문에 메모리에서 제거하지 않고 남겨두었다.
이렇게 지역 변수를 남겨두는 현상 자체를 클로저라고 부르기도 하고
test 함수로 생성된 공간 자체를 클로저라고 부르기도 하며,
리턴된 함수 자체를 클로저라고 부르기도 한다.
함수, 즉 코드블록으로 리턴된 지역 매개변수만 사용이 가능하며 외부에서 직접 호출하거나 접근할 수는 없다.
alert(), prompt(), confirm() 등은 자바스크립트에서 제공하는 함수로 이러한 함수를 자바 내장 함수라고 한다.
함수 이름 | 설명 |
setTimeout(function, millisecond) | 일정 시간 후 함수를 한 번 실행 |
setInterval(function, millisecond) | 일정 시간마다 함수를 반복해서 실행 |
clearTimeout(id) | TimeOut 함수 해제 |
clearInterval(id) | Interval 함수 해제 |
함수 이름 | 설명 |
escape() | 적절한 정도로 인코딩 |
unescape() | 적절한 정도로 디코딩 |
encodeURI(uri) | 최소한의 문자만 인코딩 |
decodeURI(encodedURI) | 최소한의 문자만 디코딩 |
encodeURIComponent(uriComponent) | 문자 대부분을 모두 인코딩 (알파벳과 숫자를 제외한 모든 문자를 인코딩) |
decodeURIComponent(encodedURI) | 문자 대부분을 모두 디코딩 (알파벳과 숫자를 제외한 모든 문자를 디코딩) |
함수 이름 | 설명 |
eval(string) | string을 자바스크립트 코드로 실행 |
함수 이름 | 설명 |
isFinite() | number가 무한한 값인지 확인 |
isNaN() | number가 NaN인지 확인 |
ECMAScript6 부터 함수의 매개변수에 기본 값을 사용할 수 있으며, 람다 함수처럼 화살표를 사용하여 함수를 선언할 수 있다.
다만 익명함수와 화살표 함수가 가리키는 this 가 다르므로 주의해서 사용해야 된다.
- 익명 함수: 함수 자체에 바인딩되어 있는 객체
- 화살표 함수: 전역 객체
또한 전개 연산자를 사용할 수 있는데, 전개 연산자는 말 그대로 배열에 담겨 있는 값을 모두 풀어서 하나씩 전달해준다.
전개 연산자는 함수 매개변수의 가장 마지막에 한 개만 사용할 수 있으며, 변수 이름 앞에 마침표 3개를 찍어 표시한다.