변수, 상수, 매개변수가 언제 어디서 정의되는지 알아야 하는 경우 스코프에 의해서 결정될 수 있다.
function f(x){
return x + 3;
}
f(5); // 8
x; // ReferenceError: x is not defined
위 코드의 x는 함수 f를 벗어나면 정의되지 않은 변수로 인식이 되며, f 함수의 유효범위 안에서만 동작한다. 이 때 x의 스코프는 f라고 할 수 있다.
매개변수x에 대해서 함수가 스코프라고 해도 실제 호출되기 전까지는 존재하지 않는다. 함수 호출 후에 연산을 끝내고 제어권을 반환하면 매개변수가 스코프 밖으로 사라진다.
const x = 3;
function f(){
console.log(x);
console.log(y);
}
{ // new scope
const y = 5 ;
f();
}
함수를 정의할 때, 함수 스코프에 어떤 변수를 담고 있는지 바로 알 수 있다.
new scope에서 y를 선언하고 바로 f를 호출해도 x의 스코프는 f가 되지만 y는 그렇지 않다.
let name = "Irena"
let age = 25;
function greet(){
console.log(`Hello, ${name}!`);
}
function getBirthYear(){
return new Date().getFullYear() - age;
}
모든 컨텍스트를 통틀어 암시적으로 주어지는 스코프를 전역 스코프라고 한다. 즉 전역 스코프에서 선안한 변수는 모든 종류의 스코프에서 확인할 수 있다.
전체 컨텍스트 어디에서도 name과 age를 변경을 할 수 있다. greet, getBirthYear은 이 전역 변수에 의존하기 때문에 자칫 나중에 원하지 않는 결과가 발생할 수 있다.
let user = {
name: "Irena",
age: 25,
}
function greet(user){
console.log(`Hello, ${name}!`);
}
function getBirthYear(user){
return new Date().getFullYear() - age;
}
name과 age를 user 객체에 담고 각 함수의 파라미터에 명시적으로 user를 넘겨주면 전역 스코프의 변수에 덜 의존할 수 있다.
console.log('before block');
{
console.log('inside block');
const x = 3;
console.log(x); // 3
}
console.log(`outside block; x = ${x}`); //ReferenceError
중괄호로 묶은 유효범위에서 블록스코프는 그 블록에만 보이는 식별자를 의미한다. x는 블록 안에서 정의됐고 그 밖의 범위에선 x가 스코프 밖으로 사라져서 정의되지 않은 에러가 발생한다.