Posts /

Scope

Twitter Facebook Google+
18 Apr 2019

스코프(Scope)

자바스크립트에서 스코프란 어떤 변수들에 접근할 수 있는지를 정의합니다. 스코프엔 두 가지 종류가 있는데요, 전역 스코프(global scope)지역 스코프(local scope)가 있습니다.

전역스코프(Global Scope)

변수가 함수 바깥이나 중괄호 {} 바깥에 선언되었다면, 전역 스코프에 정의된다고 합니다.

const globalVariable = 'some value'

전역 변수를 선언하면, 여러분의 코드 모든 곳에서 해당 변수를 사용할 수 있습니다. 심지어 함수에서도 말이죠.

const hello = 'Hello CSS-Tricks Reader!'
function sayHello () {
  console.log(hello)
}
console.log(hello) // 'Hello CSS-Tricks Reader!'
sayHello() // 'Hello CSS-Tricks Reader!'

비록 전역 스코프에 변수를 선언할 수는 있어도, 그러지 않는 것이 좋습니다. 왜냐하면, 두 개 이상의 변수의 이름이 충돌하는 경우가 생길 수도 있기 때문이죠. 만약 변수를 constlet을 사용하여 선언했다면, 이름에 충돌이 발생할 때마다 에러가 발생합니다. 이렇게 되면 안 되죠.

// Don’t do this!
let thing = 'something'
let thing = 'something else' // Error, thing has already been declared

만약 var를 이용하여 변수를 선언했다면, 두 번째 변수가 첫 번째 변수를 덮어쓰게 됩니다. 이러면 디버깅이 어려워지기 때문에 이런 식으로 사용하면 안 됩니다.

// Don’t do this!
var thing = 'something'
var thing = 'something else' // perhaps somewhere totally different in your code
console.log(thing) // ‘something else’

그래서 여러분은 언제나 전역 변수가 아닌, 지역 변수로써 변수를 선언해야 합니다.

지역 스코프 (Local Scope)

여러분 코드의 특정 부분에서만 사용할 수 있는 변수는 지역 스코프에 있다고 할 수 있습니다.이런 변수들은 지역 변수라고 불리죠.

자바스크립트에서는 두 가지의 지역 변수가 존재합니다. 바로 함수 스코프(function scope)블록 스코프(block scope)죠.

함수 스코프(Function Scope)

여러분이 함수 내부에서 변수를 선언하면, 그 변수는 선언한 변수 내부에서만 접근할 수 있습니다. 함수 바깥에서는 해당 변수에 접근할 수 없죠.

아래의 예제를 살펴보면 변수 hellosayHello의 스코프 내에 존재한다는 것을 알 수 있습니다.

function sayHello () {
  const hello = 'Hello CSS-Tricks Reader!'
  console.log(hello)
}
sayHello() // 'Hello CSS-Tricks Reader!'
console.log(hello) // Error, hello is not defined

블록 스코프(Block Scope)

여러분이 중괄호{} 내부에서 const 또는 let으로 변수를 선언하면, 그 변수들은 중괄호 블록 내부에서만 접근할 수 있습니다.

다음 예제에서 볼 수 있듯이 변수 hello는 중괄호 내부의 스코프에 존재합니다.

{
  const hello = 'Hello CSS-Tricks Reader!'
  console.log(hello) // 'Hello CSS-Tricks Reader!'
}
console.log(hello) // Error, hello is not defined

함수 호이스팅(Function hoisting)과 스코프

함수가 함수 선언식(function declaration)으로 선언되면, 현재 스코프의 최상단으로 호이스팅(hoist) 됩니다.

다음 예제에서 두 가지 경우는 같은 결과를 보입니다.

// This is the same as the one below
sayHello()
function sayHello () {
  console.log('Hello CSS-Tricks Reader!')
}
// This is the same as the code above
function sayHello () {
  console.log('Hello CSS-Tricks Reader!')
}
sayHello()

반면 함수가 함수 표현식(function expression)으로 선언되면, 함수는 현재 스코프의 최상단으로 호이스팅되지 않습니다.

sayHello() // Error, sayHello is not defined
const sayHello = function () {
  console.log(aFunction)
}

이렇게 두 방식의 행동이 다르기 때문에, 함수 호이스팅은 혼란스러울 수 있으므로 사용하면 안 됩니다. 언제나, 함수를 호출하기 전에 선언해놓아야 합니다.

함수는 서로의 스코프에 접근할 수 없다

함수들이 각각 선언되었을 때, 서로의 스코프에는 접근할 수 없습니다. 어떤 함수가 다른 함수에서 사용되더라도 말이죠.

아래의 예제에서, 함수 second는 변수 firstFunctionVariable에 접근할 수 없습니다.

function first () {
  const firstFunctionVariable = 'I’m part of first'
}
function second () {
  first()
  console.log(firstFunctionVariable) // Error, firstFunctionVariable is not defined
}

네스팅된 스코프(Nested scopes)

함수가 다른 함수 내부에서 정의되었다면, 내부 함수는 외부 함수의 변수에 접근할 수 있습니다. 이런 행동을 렉시컬 스코핑(lexical scoping)이라고 부르죠.

하지만, 외부 함수는 내부 함수의 변수에 접근할 수 없습니다.

function outerFunction () {
  const outer = 'I’m the outer function!'

  function innerFunction() {
     const inner = 'I’m the inner function!'
     console.log(outer) // I’m the outer function!
  }

  console.log(inner) // Error, inner is not defined
}

출처 사이트


Twitter Facebook Google+