
자바스크립트는 웹 브라우저에서 사용하기 위해 만들어진 프로그래밍 언어입니다. 주로 웹 브라우저 상에서 UI를 동적으로 보여주기 위해 사용해왔으며 기존에는 브라우저에서만 사용했던 언어이지만, 이제는 단순히 웹 페이지에서만 국한되지 않고 Node.js 런타임을 통하여 서버 쪽에서도 사용할 수 있게 되었습니다.
변수와 상수는 특정 이름에 특정 값을 담을 때 사용됩니다. 변수를 한번 선언하면 똑같은 이름으로 선언할 수 없습니다. 단, 다른 블록 범위 내에서는 똑같은 이름으로 사용 가능합니다.
변수에는 var, let, const가 있으며 var와 let의 차이점은 다음과 같습니다.
var은 함수 범위(Function scope)를 가집니다. 즉, 변수가 선언된 함수 내에서 유효하며, 함수 외부에서는 접근할 수 없습니다.
반면 let은 블록 범위(Block scope)를 가집니다. 변수가 선언된 블록(예를 들어 if 문, for 문, while 문, 또는 단순 중괄호 {}로 감싼 영역) 내에서만 유효합니다.
var은 같은 이름의 변수를 같은 범위 내에서 여러 번 선언할 수 있습니다.
반면 let은 같은 범위 내에서는 같은 이름의 변수를 재선언할 수 없습니다.
function testVar() {
var x = 1;
if (true) {
var x = 2; // 같은 변수 x 재선언
console.log(x); // 출력: 2
}
console.log(x); // 출력: 2
}
function testLet() {
let y = 1;
if (true) {
let y = 2; // 다른 범위 내의 새로운 변수 y
console.log(y); // 출력: 2
}
console.log(y); // 출력: 1
}
testVar();
testLet();
const는 상수이며, 한번 선언하고 값이 바뀌지 않는 값을 의미합니다. 값이 고정적이며 변수와 마찬가지로 상수를 선언할 때도 한번 선언했으면 같은 이름으로 선언할 수 없습니다.
현대 JavaScript에서는 코드의 가독성을 높이기 위해 var 대신 let 또는 const를 사용할 것을 권장하고 있습니다.
스코프(scope)는 변수가 접근 가능한 범위를 의미합니다. 자바스크립트에는 전역 스코프, 함수 스코프, 블록 스코프 세 가지 타입의 스코프가 존재합니다.
전역 스코프(Global Scope)
전역 스코프에서 선언된 변수는 코드의 어디에서나 접근할 수 있습니다.
함수 스코프(Function Scope)
함수 내에서 var 키워드로 선언된 변수는 해당 함수 내에서만 접근 가능하고, 함수 밖에서는 접근할 수 없습니다.
블록 스코프(Block Scope)
let과 const 키워드를 사용해 선언된 변수는 블록 스코프를 가집니다. 즉, 해당 변수는 선언된({}로 둘러싸인 코드 부분) 내에서만 접근이 가능합니다.
var 키워드는 함수 스코프를 가집니다. 즉, var로 선언된 변수는 선언된 함수의 내부에서 어디든지 접근할 수 있지만, 함수의 밖에서는 접근할 수 없습니다.
하지만 let과 const는 블록 스코프를 가집니다. 따라서 블록 내에서 선언된 let이나 const 변수는 해당 블록 내에서만 접근할 수 있습니다.
function test() {
let x = 10;
if (true) {
let x = 20; // 이 "x"는 위의 "x"와는 다른 변수입니다.
console.log(x); // 20
}
console.log(x); // 10
}
test();
변수 호이스팅이란 자바스크립트 엔진이 var 키워드로 선언된 모든 변수를 스크립트나 함수의 최상단으로 끌어올리는 현상을 말합니다.
이 때 중요한 점은 변수의 선언만 호이스팅되며, 초기화는 원래 코드에서 실행되는 위치에서 발생한다는 점입니다.
console.log(x); // 결과는?
var x = 5;
console.log(x); // 결과는?
위의 코드 첫 번째 결과는 undefined이고 두 번째 결과는 5가 나옵니다. 이는 자바스크립트 엔진이 스크립트를 실행하기 전에 x의 선언을 끌어올려서 스크립트의 최상단에 놓습니다. 이때 x의 초기화는 원래 그 자리에서 이루어집니다.
var로 선언된 변수를 동일한 스코프 내에서 다시 선언하면, 두 번째 선언은 사실상 무시되고, 변수의 값이 변경될 뿐입니다.
var x = 10;
var x = 20;
console.log(x); // 20
위의 코드에서 두 번째 var x는 변수를 새로 선언하는 것이 아니라, 이미 선언된 x에 새 값을 할당하는 것입니다.
반면 let과 const는 동일한 스코프 내에서 같은 이름의 변수를 다시 선언하려고 하면 에러를 발생시킵니다.
변수나 상수를 선언하게 될 때, 숫자 외에 다양한 타입의 값들을 할당할 수 있습니다.
없음을 의미하는 데이터 타입의 종류입니다. null은 주로 이 값이 없다! 라고 선언할 때 사용하며 고의적으로 설정하는 값입니다. 반면 undefined는 아직 값이 설정되지 않은 것을 의미합니다. 변수를 선언했지만 값을 지정해주지 않을 때 undefined라고 표시됩니다.논리 연산자의 순서는 NOT -> AND -> OR 순으로 적용됩니다.
==와 ===의 차이에 대해서 알아봅시다.
==은 타입 검사는 하지 않고 값이 동일한지를 비교합니다. 반면 === 값과 타입 모두 동일한 지를 비교합니다.
const a = 1;
const b = '1';
const equals = a == b;
console.log(equals); // true 반환
--------------------------------------------------------
// 0과 false도 같은 값으로 간주한다.
const a = 0;
const b = false;
const equals = a == b;
console.log(equals); //true
--------------------------------------------------------
// undefined과 null도 같은 값으로 간주한다.
const a = null;
const b = undefined;
const equals = a == b;
console.log(equals);
--------------------------------------------------------
const value = 1 === '1'; // false 반환
const value = 'a' !== 'b'; // true 반환
// 0과 false, undefined과 null 값을 비교해도 fasle를 반환
두 문자열을 붙일 때에 +를 사용할 수 있습니다.
const a = '안녕';
const b = '하세요';
console.log(a + b); // 안녕하세요
switch (device) {
case 'iphone' :
console.log('아이폰!');
break;
case 'ipad' :
console.log('아이패드!');
break;
default:
console.log('모르겠다...');
}
function hello(name) {
console.log(`Hello, ${name}!`);
}
hello('velopert');
화살표 함수
화살표 함수는 function 키워드 대신에 => 문자를 사용해서 함수를 구현합니다. 좌측에는 함수의 파라미터를, 화살표의 우측에는 코드 블록이 들어옵니다.
const add = (a, b) => {
return a + b;
};
console.log(add(1, 2));
const getGrade = score => {
if (score === 100) {
return 'A+';
} else if (score >= 90) {
return 'A';
} else if (score === 89) {
return 'B+';
} else if (score >= 80) {
return 'B';
} else if (score === 79) {
return 'C+';
} else if (score >= 70) {
return 'C';
} else if (score === 69) {
return 'D+';
} else if (score >= 60) {
return 'D';
} else {
return 'F';
}
};
const grade = getGrade(90);
console.log(grade);
this 키워드를 어떻게 처리하는지에 있습니다. 일반 함수에서는 this는 그 함수가 호출되는 컨텍스트에 따라 달리집니다. 즉, 함수가 어떻게 호출되었는지에 따라 this가 바인딩 됩니다.let testObj = {
name: "Test",
showName: function() {
console.log(this.name);
}
};
testObj.showName(); // "Test", 여기서 `this`는 `testObj`를 가리킵니다.
---------------------------------------------------
// 같은 함수를 독립적으로 호출하면 this는 전역 객체(window나 undefined)를 가리킵니다.
let testObj = {
name: "Test",
showName: function() {
console.log(this.name);
}
};
let standaloneFunc = testObj.showName;
standaloneFunc(); // undefined, 여기서 `this`는 전역 객체를 가리킵니다.
화살표 함수에서 this 는 함수가 정의된 시점의 this 를 상속받습니다. 이를 렉시컬 바인딩(Lexical Binding)이라고 합니다. 이 경우 this 는 함수를 호출하는 방법에 관계 없이 항상 같은 값을 가리킵니다.
렉시컬 바인딩(Lexical Binding)은 정적 스코프(Static Scope)를 의미합니다. 즉, 변수가 선언된 위치에 따라 그 범위(scope)와 바인딩되는 값을 결정하는 방식을 의미합니다.
자바스크립트의 화살표 함수는 this를 렉시컬 바인딩 방식으로 처리합니다. 즉, 화살표 함수의 this는 함수가 정의된 시점의 this를 가리키며, 이는 함수가 어떻게 호출되었는지와는 관계가 없습니다.
let myObj = {
value: 'Hello, World!',
showValue: function() {
console.log(this.value); // 이 경우 'this'는 'myObj'를 가리킵니다.
},
showValueDelayed: function() {
setTimeout(() => {
console.log(this.value); // 화살표 함수를 사용하여 'this'가 렉시컬하게 바인딩되었습니다.
}, 1000);
}
};
myObj.showValue(); // "Hello, World!"를 출력합니다.
myObj.showValueDelayed(); // 1초 후에 "Hello, World!"를 출력합니다.
위의 코드에서 화살표 함수의 this는 렉시컬 바인딩에 의해 myobj를 가리키므로, showValueDelayed 메서드가 호출되는 시점에서의 this를 기억하고 있습니다. 이러한 방식으로 렉시컬 바인딩은 함수의 this를 호출하는 방법과는 독립적으로 결정하게 됩니다.
자바스크립트에서 제공하는 타이머 함수 중 하나로, 특정 시간이 지난 후에 함수를 실행하도록 예약하는데 사용됩니다.
setTimeout 내의 콜백 함수에서 this는 전역 객체를 가리키게 됩니다. setTimeout은 콜백 함수를 독립적으로 호출하기 때문입니다.
setTimeout(function, delay, param1, param2, ...)
// 여기서
// function : 실행하고자 하는 함수를 참조하거나, 실행하고자 하는 코드를 문자열로 제공한다.
// delay : 함수가 실행되기 전에 대기할 밀리초(millisecond)를 지정한다.
// param1, param2, ... : 선택적 인자들로, 실행할 함수에 전달하고자 하는 매개변수들이다.
setTimeout(function(a, b) {
console.log(a + b);
}, 3000, 5, 7); // 3초 후에 "12"를 출력합니다.
참고 자료
밸로퍼트 모던 자바스크립트