Scope란?


  • 변수가 접근가능한 범위이다.
  • 내부와 외부를 판별하는 기준은 함수이다.
    • var 키워드는 함수 단위함수가 하나의 범위.
    • let 키워드는 '{}' 중괄호가 하나의 범위.
  • 내부에서 외부는 접근 가능하지만, 외부에서 내부는 접근 불가능 하다.

scope.gif

var a = 'out'; // 함수 밖에서 변수를 선언하면 전역변수

function foo () {
   var b = 'in'; //함수 내에서 변수를 선언하면 지역변수
   console.log(b); // 'in'
   console.log(a); // 'out' 
} 

foo();

console.log(b); // error 외부에서 내부 접근이 불가능 하다.
  • 함수가 범위의 기준이 된다.
  • 내부에서 외부는 접근 가능하지만, 외부에서 내부는 접근 불가능 하다.
var a = 'global'; // 전역변수

function foo () {
   var a = 'local'; // 지역변수
   alert('함수안 ' , a); // 'local'
}

foo();

alert('함수밖 ' + a); // 'global'
  • 함수 안에서 같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 지역변수를 우선순위를 가진다
var a = 'global'; // 전역변수

function foo () {
   a = 'local'; // 전역변수 a의 'global' 을 'local'로 재할당
   alert('함수안 ' + a); // 'local'
}

foo();

alert('함수밖 ' , a); // 'local'
  • 선언 키워드 없이 함수 안에서 전역변수와 같은 변수에 값을 할당하면 전역 변수의 값을 재할당 하는 것이다.

for loopvar



function foo () {
var a = 5;
for (var i=0; i < a; i++) {
  i = i + 1;
}
   console.log(i); // 6 -> i는 foo함수의 scope
}

foo();

위와 같은 경우 i++을 하고 i = i + 1 하면서 콘솔에 6이 찍힌다.

  • i는 foo함수의 scope를 가진다.

let , const Socpe


letconst는 블록 단위로 스코프가 정해진다.

function foo () {
  let a = 5;
  for (let i=0; i < a; i++) {
    i = i + 1;
  }
   console.log(i); // erro 
}

foo();

letconst키워드는 {} 중괄호 scope 범위를 가진다.
i는 for 문 {}중괄호 scope를 가지기 때문에 console.log(i)를 실행했을 경우 중괄호 내부 변수에 접근할 수 없다.

Hoisting


hoisting


console.log(a); // undefind

var a = 1;

console.log(a); // 1

첫 번째 console.log(a);undefind가 뜨는 이유는 hoisting 때문이다.
실제로 실행될 때에는 아래와 같이 변수를 선언하는 부분이 끌어올려지는 것과 같기 때문에 var a;에 값이 할당되어 있지 않으므로 undefinde 가 된다.

var a;

console.log(a);

a=1;

console.log(a);

본인이 속한 Scope 내에서 Hoisting


var a = 'hello';

function foo () {
   alert(a); // undefind

   var a = 'world';
}

foo();

alert(me);undefind가 된다.
아래와같이 Scope 내에서 Hoisting 되기 때문이다.

var a = 'hello';

function foo () {
   var a;

   alert(a);

   a = 'world';
}

foo();

함수 표현식 Hoisiting


변수를 만들고 함수를 할당하는 방식을 함수 표현식이라고 한다.

fn(); // ERROR

var fn = funcion () {
   console.log('hello world');
};

fn();

함수 표현식 또한 변수에 함수를 할당하면 아래와 같이 변수 var fn;hoisting 되고 var fn;undefind이기 때문에 var fn;를 호출하면 undefind가 호출되면서 ERROR 가 뜨게된다.

var fn;

fn(); // ERROR

var fn = funcion () {
   console.log('hello world');
};

fn();

함수 선언식 Hoisiting


아래와 같이 함수 선언식으로 함수를 정의할 경우 함수가 모두 호출된다.

fn();

function fn () {
   console.log('hello world');
}

fn();

아래와 같이 함수 자체가 hoistiong 된다.

function fn () {
   console.log('hello world');
}

fn();

fn();

Primitive vs Reference


Primitive 원시형

var a = 1;
var b = 1;

var c = 'hello';
var d = 'hello';

console.log(a === b);  // true
console.log(c === d);  // true
  • a와 b는 같다.
  • c와 d는 같다.

Reference 참조형

var arr1 = [ 1, 2, 3 ];
var arr2 = [ 1, 2, 3 ];

var obj1 = {a: 1, b: 2};
var obj2 = {a: 1, b: 2};

console.log(arr1 === arr2);  // false
console.log(obj1 === obj2);  // false

arr1과 arr2 모두 선언한 후 배열을 만들어 생성하였다.
위와 같은 경우 arr1과 arr2가 같아 보일 수 있지만 실제로 arr1과 arr2는 다른 배열이다. 서로의 위치에서 만들어진 값으로 위치 값이 다르기 때문에 false이다.

var arr1 = [ 1, 2, 3 ];
var arr2 = arr1;

var obj1 = {a: 1, b: 2};
var obj2 = obj1;

console.log(arr1 === arr2);  // true
console.log(obj1 === obj2);  // true

arr1arr1에 할당한 것으로 위치 값이 같이 때문에 true 이다.