본문 바로가기
Javascript

블록스코프, 함수스코프 란(feat. var, const, let)

by for2gles 2021. 8. 9.
반응형

오늘은 Javascript의 기본기를 다져보는 시간을 가져보려고 한다.

var 과 const, let의 차이를 알아보려고 한다.

 

일단 블록 스코프, 함수 스코프의 차이를 말하기에 앞서 스코프란 무엇인지 알아보자.

스코프(Scope)란?

단순하게 한국말로 직역하면 '범위' 이다.

Javascript 에서의 스코프는 '변수에 접근할 수 있는 범위'라고 생각하면 된다.

 

 

블록스코프, 함수스코프란?

블록스코프에는 let(수정가능), const(수정불가)가 있고, 블록({ })마다 새로운 스코프가 새로 재정의 된다라고 생각하면 된다.

function test_func(){
  let test1 = 'hi1';
  const test1 = 'hi2';
  console.log(test1, test2); // hi1 hi2
}
test_func();
console.log(test1, test2); // ReferenceError: Can't find variable: test1

if(2 > 1){
  let test1 = 'hi1';
  const test2 = 'hi2';
  console.log(test1, test2); // hi1 hi2
}
console.log(test1, test2); // ReferenceError: Can't find variable: test1

함수스코프에는 var이 있고, 함수(function(){ })마다 새로운 스코프가 재정의된다라고 생각하면 된다.

function test_func(){
  var test1 = 'hi1';
  console.log(test1); // hi1
}
test_func();
console.log(test1); // ReferenceError: Can't find variable: test1

if(2 > 1){
  var test2 = 'hi2';
  console.log(test2); // hi2
}
console.log(test2); // hi2

함수스코프일 경우에는 if 블록 내부에서 생성된 변수인 test2 가 블록이 끝난 이후에도 사용이 가능하다.

 

정리하자면

var : 함수스코프

const : 블록스코프(수정불가)

let : 블록스코프(수정가능)

이다.

 

추가 궁금사항

const는 수정이 불가하다고 하였는데, Array 나 Object일 때, 내부 값도 수정이 불가할까?

Array

const test = [];

test.push('test');
console.log(test); // ['test']

test = ['test2']; // TypeError: Attempted to assign to readonly property.

Object

const test = {};
test['test'] = 'hi';
console.log(test); // {test: "hi"}

test = {test2: "hi2"}; // TypeError: Attempted to assign to readonly property.

결론: Array와 Object 내부는 const와 상관없이 변경이 가능하고, 직접적인 변수 수정은 차단된다.

 

외부에서 선언된 변수를 내부에서 재선언 할 경우 어떻게 작동될까?

var

var test = 1;
if(3 > 2){
  var test = 2;
  console.log(test); // 2
}
console.log(test); // 2

var test2 = 1;
function test_func(){
  var test2 = 2;
  console.log(test2); // 2
}
test_func();
console.log(test2); // 1

const, let

const test1 = 1;
let test2 = 1;
if(3 > 2){
  const test1 = 2;
  let test2 = 2;
  console.log(test1, test2); // 2 2
}
console.log(test1, test2); // 1 1

const test3 = 1;
let test4 = 1;
function test_func(){
  const test3 = 2;
  let test4 = 2;
  console.log(test3, test4); // 2 2
}
test_func();
console.log(test3, test4); // 1 1

결론: 재선언을 한다 하여도 오류가 나지 않고 선언자에 맞게 본인 스코프에 맞추어 새롭게 변수가 선언된다.

 

재밌는 테스트

//테스트1
for(let i = 0; i < 3; i++){
  setTimeout(function(){
    console.log(i);
  }, 1000)
}
console.log('done');

// 'done'
// 0
// 1
// 2

//테스트2
for(var i = 0; i < 3; i++){
  setTimeout(function(){
    console.log(i);
  }, 1000)
}
console.log('done');

// 'done'
// 3
// 3
// 3

//테스트3
let i;
for(i = 0; i < 3; i++){
  setTimeout(function(){
    console.log(i);
  }, 1000)
}
console.log('done');

// 'done'
// 3
// 3
// 3

 

반응형

댓글