2024.09.11 (Day 7) - JavaScript Scope 와 Hoisting

반응형

변수와 호이스팅

• 호이스팅(Hoisting)은 ‘무언가를 끌어올린다’ 라는 의미의 단어로

아래에 선언된 변수를 위에서 사용하게 해주는 기법이다.

코드는 위에서 아래로 흐르면서 실행됨으로 코드 위치만 보자면 변수가 아랫부분에 선언되어 있다면

윗 부분이 실행될때는 변수가 선언되지 않은 상태가 됨으로 에러가 발생되어야 하는데

실행시에 아래에 작성한변수 선언 부분을 자동으로 위로 끌어올려서 에러 없이 코드가 진행되게 해주는 기법이다.

 

• 변수를 선언하는 방법은 var, let, const 예약어중 하나를 이용하며

이중 호이스팅을 지원하는 변수 선언은 var 이다.

 

• 코드 아래에 선언된 변수가 호이스팅이 되면 어디선가 값 대입이 되기 전까지는 undefined 상태가 된다.

 

• 변수 선언을 let 과 const 로도 선언할 수 있는데 let, const 로 선언된 변수는 호이스팅이 지원되지 않는다.

 

▼ var 호스팅

    //var hoisting test
    console.log(`step1, data1 = ${data1}`);
    data1 = 10    

    console.log(`step2, data1 = ${data1}`);
    var data1 = 10

    console.log(`step3, data1 = ${data1}`);

 

선언된 변수의 선언부분만 (값 할당은 빼고) 위로 올린다

 

▼ let, const 호이스팅

    // console.log(data2); //error
    // console.log(data3); //error
    let data2 = 10
    const data3 =30
    //==>var에 한해서만 호스팅에 의해 선언위치 위에서 변수 이용가능

 

함수와 호이스팅

• 변수와 마찮가지로 함수도 코드의 윗 부분에서 함수가 선언되고

그 하위 어디선가 선언된 함수를 호출해서이용하는 것이 일반적이다.

그런데 함수의 선언위치와 함수의 이용 위치가 변경되어 코드 아랫부분에 선언된 함수를

코드 윗 부분에서호출할 수 있게 지원이 되며 이를 함수의 호이스팅이라고 한다.

• 함수의 호이스팅은 함수 선언식에서 제공되며 표현식 함수는 호이스팅이 지원되지 않는다.

 

 

    console.log(myFun1()); //myFun1 call
    function myFun1() {
        return 'myFun1 call'
    }

 

 

스코프

• 같은 영역에서 실행되는 코드를 { } 로 묶어서 개발한다.

그렇기에 하나의 { } 내에 선언된 코드들은 동일 스코프에서 실행된다는 표현을 한다.

 

• { } 에 의해 코드가 묶여야 하는 대표적인 것이 함수, for, if 등이다.

함수를 선언하면서 function a() { } 형식으로 함수가 호출될 때 실행되어야할 코드를 { } 로 묶는다.

이 { } 내의 코드들은 함수 스코프에서 실행되는 코드들입니다.

 

 

▼ 중복선언

• 중복 선언이란 같은 동일 이름으로 변수가 중복되어 선언되는 것을 의미한다.

스코프와 관련있으며 동일 스코프내에서 중복인지? 다른 스코프에서 중복 선언인지에 따라 다르다.

 

▼ 다른 스코프에서 중복 선언

• 스코프란 { } 로 묶이는 코드의 영역을 의미하며

어떤 스코프 내에서 선언된 변수는 그 스코프에만 영향을미치게 된다.

그렇기에 다른 스코프에 동일 이름으로 변수가 중복되었다고 하더라도

두 변수는 개별 변수가 되며 상호 영향을 미치지 않게 된다.

//중복 선언
var data1 = 10
let data2 = 10
const data3 = 10

var data1 = '홍길동'
// let data2 = '홍길동'//error
// const data3 = '홍길동'//error

//==>동일 스코프에서 중복 선언은 var 에 한해서만 지원된다


//scope 가 다른 위치에서 중복 선언
let data4 = '홍길동'//global scope

const myFun = () => {
  let data4 = '김길동'//local scope
  console.log(`in function ${data4}`)//in function 김길동
}
myFun()
console.log(`out function ${data4}`)//out function 홍길동

//==>스코프가 다르다면 변수 중복 선언 가능하다. let, const 도가능
//local 우선이다.
//변수명을 의미있는 단어로 주는 것이 기본임으로
//변수명을 중복해서 local 변수를 자주 만든다

 

▼ 동일 스코프에서 변수 중복 선언

• 동일 스코프내에서 이미 선언된 변수명과 동일한 변수를 다시 중복으로 선언하는 것은 var 로 선언된 변수는 가능하지만 let, const 로 선언된 변수는 불가능하다.

//함수 중복 선언 좀더 살펴보기
function myFun1() {console.log('step1');}
function myFun1() {console.log('step2');}
myFun1() //step2


var myFun2 = function(){console.log('stea1');}
var myFun2 = function(){console.log('stea2');}
myFun2() //step2

let myFun3 = function () {console.log('step1');}
// let myFun3 = function () {console.log('step2');} //errer
//함수 중복 선언 : 선언식 함수와 var 에 대입되는 표현식 함수만 가능

 

▼ var 은 함수 스코프만 지원한다

• 어떤 코드가 실행되는 영역을 스코프라고 하며 어떤 스코프에 선언된 변수는

그 스코프에서만사용되고 다른 스코프에는 영향을 미치지 않게 하는 것이 기본이다.

 

•또한 var 로 선언한 변수는 함수 스코프만 지원하며 for, if 등의 다른 스코프는 지원하지 않는다.

 

//scope
//모든 소프트웨어 언어 에서는 하나의 scope ({})내에 선언된
//변수, 함수는 그 스코프내에서만.
var name1 = '섭이'
const someFun = () => {
  var name1 = '섭이2'
  console.log(`in someFun 1, name1 = ${name1}`);
  for(let i=0; i<1; i++){
    var name1 = '섭이3'
    console.log(`in someFun 1, in for, name1 = ${name1}`);
  }
  console.log(`in someFun 2, name1 = ${name1}`);
  if(true){
    var name1 = '섭이4'
    console.log(`in someFun 2, in if, name1 = ${name1}`);
  }  
  console.log(`in someFun 3, name1 = ${name1}`);
}
someFun()
console.log(`out someFun, name1 = ${name1}`);

in someFun 1, name1 = 섭이2
in someFun 1, in for, name1 = 섭이3 
in someFun 2, name1 = 섭이3 
in someFun 2, in if, name1 = 섭이4 
in someFun 3, name1 = 섭이4
out someFun, name1 = 섭이

var 로 선언된 변수, 함수 scope 만 지원한다. for, if 지원하지 않는다.

 

▷ var에서 let으로 바꾼다면

let name1 = '섭이'
const someFun = () => {
  let name1 = '섭이2'
  console.log(`in someFun 1, name1 = ${name1}`);
  for(let i=0; i<1; i++){
    let name1 = '섭이3'
    console.log(`in someFun 1, in for, name1 = ${name1}`);
  }
  console.log(`in someFun 2, name1 = ${name1}`);
  if(true){
    let name1 = '섭이4'
    console.log(`in someFun 2, in if, name1 = ${name1}`);
  }  
  console.log(`in someFun 3, name1 = ${name1}`);
}
someFun()

console.log(`out someFun, name1 = ${name1}`);

 

in someFun 1, name1 = 섭이2 
in someFun 1, in for, name1 = 섭이3 
in someFun 2, name1 = 섭이2 
in someFun 2, in if, name1 = 섭이4 
in someFun 3, name1 = 섭이2 
out someFun, name1 = 섭이


즉 let은 함수, for,if 스코프 지원한다.

 

반응형