[JavaScript] Types, Scope, Closure

12947 단어 JavaScriptJavaScript

자바스크립트 자료형

원시 자료형(primitive type)

string, number, bigint, boolean, undefined, symbol, null

  • 옛날 메모리가 작던 시절, 변수에는 하나의 데이터만 담을 수 있었기 때문에 옛날부터 썼던 자료형이라고 해서 원시 자료형이라고 불린다.
  • 변수에 값이 할당된다.

참조 자료형(reference type)

array, object, function (원시 자료형이 아닌 모든 자료형)

  • 옛날에는 문자열로 배열과 비슷하게 만들어서 사용했고, 그 이후 새로운 자료형들이 나왔다.
  • 자바스크립트는 참조 자료형 변수에 주소값을 할당하고, 실제 데이터는 해당 주소의 heap 메모리에 할당한다.

Scope

{
  { 
    {}
  }
}
// 제일 바깥쪽 scope : global scope (전역 스코프)
// 안쪽 scope: local scope (지역 스코프)
// 전역변수(전역 스코프의 변수), 지역변수(지역 스코프의 변수)
// 안쪽 스코프에서는 바깥쪽 스코프 변수에 접근 가능하지만, 밖에서는 안에 접근하지 못한다.

// block scope : {}, if {}, for {}, 화살표 함수 {}
// function scope : function {}

// var 키워드는 는 블록 스코프를 무시하고 함수 스코프만 적용되므로 사용이 권장되지 않음.
// 예) for 문에서 var = i 한다면 i 값을 스코프 밖에서도 접근할 수 있음.
// 또한 재선언을 해도 오류를 내지 않음. 
var a = 1; var a = 2;
// 선언 없이 값을 할당하면 var 로 처리됨. 
c = 1; // var c = 1;

// const 는 재선언, 재할당 모두 불가.
  • html, js 파일을 만든 뒤 크롬 콘솔의 sources 탭에서 breakpoint 지정, scope 및 watch 기능 등의 디버깅 가능.

window 객체

window 객체는 브라우저에 존재하는 객체이다. 브라우저 창 (window)을 의미하여, 전역 영역을 담고 있다.

//var 로 선언된 전역변수 및 전역함수는 window 객체에 속하게 된다. (다른 키워드는 안됨)
var a = 1;
window.a // 1
// var 로 선언한 변수가 window 객체의 기능을 덮어씌워서 문제가 발생할 수도 있음.
var console = 1;
console.log('abac') // Error: console.log is not a function

Tips

  • 'strict mode'를 쓰면 값의 재선언, 키워드 없는 선언 등의 오류를 잡아준다.
  • 전역 변수를 너무 많이 만들면 협업시 이름이 겹쳐 충돌이 발생할 수 있다.

JavaScript Closure

[Stack Overflow] How do JavaScript closures work?

클로져는 다음 두 개의 조합이다:

  1. 내부 함수
  2. 외부 함수의 데이터 (변수, 인자 등)의 reference - lexical environment

클로져는 함수가 호출됨과 동시에 생성된다.

클로저 함수의 특징

  1. 함수 내부에 함수가 존재한다.
  2. 내부 함수가 외부 함수의 변수에 접근한다.
  3. 외부 함수가 종료되어도 (call stack 에서 해제되어도) 내부의 환경 (인자 값 등)이 메모리에 저장되어 소멸되지 않는다.
    • lexical environment 데이터는 stack 혹은 heap 메모리에 적절하게 할당된다.
// 클로저 함수의 기본 형태
const adder = function(first) {// 외부함수
  let a = 'hello';
  return function(second) {// 내부 함수를 return
    console.log(a); // 외부 스코프의 변수에 접근
    return first + second; // 외부 함수의 parameter 에 접근
  }
}
// 화살표 함수로 만들 때
const adder = first => second => first + second;

const add5 = adder(5);
add5(3); // hello 출력, return 값은 8.
// adder(5)(3) 과 같다. 첫번째 값이 5로 고정된 새로운 함수를 만듦.

클로저 함수 활용

const tagMaker = function(tag) {
    return function(content) {
        return `<${tag}>${content}</${tag}>`
    }
}

const divMaker = tagMaker('div'); // div 를 만들기 위한 함수로 만든다.
divMaker('나는 천재야'); // <div>나는 천재야</div>

Closure Module Pattern

클로저를 이용해 내부 함수 단 하나만 리턴하는 것에 그치지 않고, 여러개의 내부 함수를 객체에 담아 리턴한다. 또한 내부에 변수를 만들어 외부에서 접근하지 못하게 할 수 있다. (c++의 private 멤버변수처럼 사용)

const makeCounter = function(){
  let count = 0; // 이 변수는 내부 환경으로써 저장된다.
  return { // 객체에 여러개의 내부함수를 담는다.
    // 객체의 key 는 함수를 value 로 가질 수 있다. (함수주소)
    increase: function() { count++; },
    decrease: function() { count--; },
    getCount: function() { return count; }
  };
}

const counter1 = makeCounter(); // 객체를 return 하기때문에 counter1 은 객체가 된다.
counter1.increase; // 실행 X
counter1.increase(); // 실행.
counter1.getCount(); // 1, count에 접근이 가능.
  • 클로저를 통해 데이터와 메소드를 같이 묶어서 다룰 수 있기에 모듈화에 유리하다.



느낀점

좋은 웹페이지 즐겨찾기