기존에 컴퓨터에 있던 이클립스로 Angular를 설치하려고 하니 계속 버전에 맞지 않는 문제로 설치가 되지 않았다.

그래서 아예 새로운 이클립스 버전을 깔고 Angular를 설치해서 프로젝트를 생성했다.


새로 설치한 이클립스 버전으로 사실 Oxygen 은 이번에 처음 알게되었다.

위키에서 확인해본 결과 2017년 6월 28일이 Oxygen 버전의 배포일이라고 되었다.

배포한지 채 한달도 지나지 않은 버전.

(가장 최근 버전을 깔면 버전 오류가 나지 않겠지!!!!라는 생각으로 깔았다......)


[Help > Eclipse Marketplaces...] 로 들어가서 angularJS를 검색하여 Angular IDE 2017 CI 7과 nodejs를 검색하여 Nodeclipse 1.0.2를 다운받았다.


이 후, 바로 Angular프로젝트를 생성할 수 있다.

마우스 우측 클릭을 해서 [ New > Project...] 를 선택한다.


팝업 창에서 Angular 폴더에 Angular Project가 있는 것을 확인할 수 있다.

기존에는 Dynamic Web Project를 생성해서 프로젝트를 선택하여 Config로 Angular로 프로젝트를 변환 시켜서 사용하는 것 같았다.


원하는 프로젝트 명을 작성하고.


위의 설정까지 하면 Server에 기본으로 Angular CLI가 생기는데, 프로젝트를 선택해서 실행시키면 아래와 같이 프로젝트가 열리게된다.





기본적으로 angularJS에 대한 내용을 알아보기 위해서는

https://angular.io

위의 URL로 이동하여 예시를 따라하거나 예제 파일을 활용할 수 있다.


먼저 위의 홈페이지로 이동하여 GETTING STARTED 화면을 보면 간단하게 프로젝트를 생성하고 확인할 수 있도록 되어있다.


우선 가장 먼저 해야할 것은

https://nodejs.org/en/download/

해당 사이트로 이동하여 node.js를 다운받아 설치한다.

해당 사이트의 화면으로 맞는 버전을 찾기 위해 위에 DOWNLOADS에 들어갔다.


필요한 버전을 찾아 다운로드를 했다.


다운로드 된 아이콘을 확인하고 설치를 시작.


Next 클릭.


설치중......


설치가 완료된 것을 확인할 수 있다.


이제 cmd(명령 프롬프트) 창을 열어 node 버전을 확인하고 실행을 시킬 수 있다.

cmd 창은 위와 같이 검색을 해서 간단하게 열 수 있다.


위와 같이 node --version을 입력 하면, 정상 설치가 완료되었을 경우 설치한 node의 버전을 확인할 수 있다.


다음에는 npm install -g @angular/cli를 입력하여 Angular CLI를 설치한다.


angular 프로젝트를 생성하기 위해서는 위의 명령어를 작성하면 된다.

(my-app은 프로젝트 명이다)


위와 같이 생성한 프로젝트 안으로 들어가서 프로젝트를 실행시키면 아래와 같은 화면이 열리는 것을 확인할 수 있다.

프로젝트가 실행되는데 어느정도의 시간이 소요된다.


가장 기본적으로 따라해볼 수 있는 내용인 것 같다.


그리고 명령 프롬프트에

ng build 를 입력하면 해당 프로젝트를 배포할 수 있는 형태로 빌드해준다.

또한, 기존에는 프로젝트를 생성해도 해당 경로에서 프로젝트가 보이지 않는데, 빌드를 하고 나면 해당 경로에서 프로젝트를 확인할 수 있다.


1. 변수 Varialble

변수는 주로 const와 let을 이용하여 선언한다.

변수 선언의 기본 형태는 아래와 같다.

// 변수에 값을 넣으면서 초기화

const myStr : String = "Hello World!";

let myNum : Number = 2017;

// 변수만 초기화

let myNum : Number;

myNum = 2017;

// 변수 타입 생략

const myStr = "Hello World!";

let myNum = 2017;

변수만 초기화하는 경우 let만 선언이 가능하며, const는 사용이 불가능하다.

한 번 정해진 변수 타입은 변경이 불가능하며, 변수를 초기화할 때 변수의 타입을 적어주지 않더라도 초기화할 값으로 컴파일러가 변수의 타입을 결정할 수 있으므로 명시적인 생략이 가능하다.


const array1 : Number[] = [2017, 6, 29];

const array2 : [Number, String] = [2017, "Thursday"];


const myArr : (Number|String)[] = [2017, "Thursday"];

myArr[0] = "2017";

타입을 설정할 때, 파이프( | )를 이용하면 여러타입 중 하나를 선택할 수 있는데, 이를 유니온 타입이라고 한다.



2. 함수 Function

기본적인 함수 형태는 같으나 차이가 있다. TypeScript는 함수에도 타입 선언이 가능하며, 타입 지정 대상은 함수로 전달되는 매개 변수와 최종 리턴 값이 될 수 있다.


function myFunc1(a : number, b : number) : number {

return a+b;

}

consle.log(myFunc1(1,2));


function myFunc2(a : number, b : number) {

return a+b;

}

consle.log(myFunc2(1,2));

위의 예제에서 둘의 차이점은 리턴 값의 타입을 선언하여 보여주는 것이며, 두 함수의 결과 값은 모두 같다.


var myFunc3 = (num : number) : number => {

return (num * num);

}


var myFunc4 = (num : number) => {

return (num * num);

}

위의 예제는 Arrow 함수를 이용하여 함수를 표현항 방식이다.


var myFunc5 = (num : number) => (num * num);

또한 위와 같이 축약형태로도 사용이 가능하다.



3. 오브젝트 objects

오브젝트는 key와 value를 쌍으로 가지는 인스턴스이다. value는 스칼라(scalar), 함수, 다른 오브젝트 등을 값으로 가질 수 있다.

var objName = {

key1 : 2017,

key2 : "value",

key3 : function() {......},

key4 : ["content1", "content2"]

};

오브젝트는 위와 같은 형태로 구현할 수 있다.

그리고 오브젝트 내에 함수를 선언하여 오브젝트의 함수로 사용이 가능하다. 아래는 오브젝트 내에 함수를 선언하여 사용하는 예제이다.

var person = {

firstName : "마루나"

lastName : "J"

sayHello : function(){}

};

person.sayHello = function() {

console.log("Hello!" + person.firstName);

);

person.sayHelo();

위와 같은 형태로 사용이 가능하다. 그리고 함수의 매개변수에 오브젝트를 넣을 수 있다.

매개 변수에 사용하는 형태는 obj 혹은 obj : {firstName : string} 처럼 사용하면 된다.



4. 인터페이스 Interfaces

클래스의 구현부가 제외된 형태의 것으로 인터페이스로 선언한 객체가 인터페이스 내에 선언한 프로퍼티나 메소드를 가지는 것을 의미한다.

실질적인 구현은 인터페이스를 사용하는 클래스에서 한다.

interface Shape {

getArea() : number;

}

class Rect implements Shape {

width : number;

height : number;

constructor(width, height) {

this.width = width;

this.height = height;

}

getArea() {

return (width * height);

}

}

위와 같은 형태가 인터페이스를 사용하는 가장 기본 형태이다. implements는 Shape 인터페이스를 사용한다고 선언하는 것이므로 Rect 클래스 안에서 인터페이스를 사용해야한다.


아래는 변수 선언 방법에 대한 내용이다.

// 기본 변수 선언

value1 : string;

// 선택적으로 변수를 사용할 수 있도록 선언

value2 ?: number;

// 읽기만 가능한 변수 선언으로 변수 수정이 불가

readonly value3 : string;

위의 readonly는 프로퍼티에서 사용이 되며, 변수에는 const로 상수 선언이 가능하다.


interface square {

color?: string;

width?: number;

}

function createSquare(config : Square) : {color : string; area : number} {......}


// 에러 발생

let mySquare = createSquare({colour : "red", width : 100});

// 성공

let temp = {colour : "red", width : 100};

let mySquare = createSquare(temp);

위에서 실패한  예제는 color 변수대신 colour 변수가 들어가있다. 이 경우 명백히 잘못된 인자가 들어간 것이므로 에러가 발생한다. 하지만 아래의 경우 temp에도 color 변수가 colour로 입력되어있는 것을 확인할 수 있다. 아래의 경우에는 colour이 temp의 변수이므로 다른 곳에서 해당 변수를 사용할 수 있다고 판단하여 에러가 발생하지 않는 것이다.


interface interFunc {

(source : string, subString : string) : boolean;

}

let mySearch : interFunc;

mySearch = function(source : string, subString : string) {

let result = source.search(subString);

if (result == -1) {

return false;

} else {

return true;

}

}

인터페이스의 함수는 파라미터와 리턴 값을 지정할 수 있다. 함수 인자 이름은 변경이 가능하며, 괄호안에 값을 넣는다. return값은 ' : '을 이용하여 선언한다.



5. 클래스 Classes

이전 게시글에서 나온 ECMAScript2016(ES6)의 클래스 설명과 차이점을 비교하면서 확인하는게 더 유용할 것 같다.

class Rect {

width : number;

height : number;

static count : number;


constructor(width : number, height : number) {

this.width = width;

this.height = height;

Rect.count++;

}

}

new Rect(10, 10);

new Rect(20, 20);

Rect.count;            // 2

위의 예제가 기본 클래스의 형태이며, ES6와는 달리 클래스 생성자에서 사용하는 변수는 클래스 내부 프로퍼티로 선언을 하여야한다. 선언하지 않을 경우 생성자에서 오류가 발생한다.

또한, ES6의 경우 static 메서드는 사용이 가능하지만 static 프로퍼티를 사용하지 못했다. 하지만 TypeScript의 경우 static 프로퍼티 사용이 가능하다. 그리고 접근 제한자(private, public, protected)가 사용이 가능하며, readonly도 사용이 가능하다. readonly는 어느 접근 제한자에도 제한없이 사용이 가능하다.

- readonly 사용 방법 : 접근제한자 readonly 변수;


상속을 위한 추상클래스(추상메소드를 가진 클래스)는 구현부가 없는 메소드를 가진 클래스이다. 객체 인스턴스는 생성이 불가능하며, 상속용으로만 사용이 가능하다.

+) 인터페이스는 모든 메소드가 추상 메소드인 반면 추상클래스는 실제 구현이 있는 메소드도 포함하여 사용 할 수 있다.



ECMAScript2015의 기본 개념에 대해 대략적으로 정리를 한 부분이다.


ECMAScript2015에서는 아래의 내용이 화면 전체 혹은 함수 내에 작성되어있는 것을 볼 수 있다.

'use strict';

이것은 '엄격모드'라고도 하며, ES6 버전에서 새롭게 추가된 기능이다. 프로그램 또는 함수를 사용할 때, 문법을 더 정확히 사용할 수 있도록 도와주는 역할로 기존에 가능했던 사용방법에서 오류가 발생할 수 있다.

- 필수 사용은 아니다.

- 모호하거나 틀린 문법에서 오류를 발생시킨다. (ex. 같은 이름의 변수 선언 등)

- IE의 경우 버전 10 이전에서는 사용이 불가하다.



1. Arrow(=>, 화살표 함수)

- ES6에서 처음 도입된 개념

- 짧은 함수 및 바인딩하지 않은 this가 arrow의 도입에 영향을 끼쳤다. (this 사용의 번거로움 해소를 위해)

- 함수 표현에 비해 구문이 짧다.

- 항상 익명으로 사용이 된다.

- 메소드가 아닌 곳에 적합하므로 생성자로 사용할 수 없다.


아래의 경우 arrow 함수 사용 형태에 대한 설명이다.

1) arrow 사용의 기본 형태

(param1, param2, ..., paramN) => {statement}

(param1, param2, ..., paramN) => expression        // {return expression}과 동일하다


2) 매개변수가 하나일 경우 괄호는 선택사항이다.

(singleParam) => {statement}

singleParam => {statement}


3) 매개변수가 없을 경우 괄호는 필수사항이다.

() => {statement}


4) 객체 리터럴 식을 반환하는 본문(body)은 괄호속에 넣어서 표현한다.

params => ({foo:bar})


5) 나머지 매개변수 및 기본 매개변수가 지원된다.

(param1, param2, ...rest) => {statement}

(param1 = defaultValue1, param2, ..., paramN = defaultValueN) => {statement}


6) 매개변수 목록 내 비구조화도 지원된다.

var f = ([a, b] = [1, 2], {x : c} = {x : a + b} => a + b + c);

f();                // 결과값


아래는 이해에 도움이 되도록 JS에서 기존 사용했던 방식과 arrow 함수를 사용한 방식이다.

// JS

function(a) { return a > 0; }


// ES6

a => a > 0


기존 콜백함수나 이벤트리스너를 arrow 함수를 이용해 새로운 방식으로 사용할 수 있다.

(콜백함수를 등록하는 시점에 this를 콜백함수에 access를 하는 경우가 발생하는데, 클로저를 이용하여 this를 속박하는 등의 방식 대신 arrow 함수로 더 효율적으로 사용할 수 있다.)


var exFunc = {

var cnt : 0,

ex1 : function(selector) {

var node = document.querySelector(selector);

node.addEventListener('click', function(evt) {

this.cnt++;

}.bind(this));

}

};

exFunc.ex1('body');

위의 내용을 아래처럼 바꿔서 사용할 수 있다.

var exFunc = {

var cnt : 0,

ex1 : function(selector) {

var node = document.querySelector(selector);

node.addEventListener('click', (evt) => {

this.cnt++;

});

}

};

exFunc.ex1('body');



아래는 바인딩되지 않는 this에 대한 예제로 arrow 함수 사용 이전에는 모든 새로운 함수는 자신의 this값을 정의해서 사용해야하는 것을 보여준다.

function addFunc() {

this.num= 0;

setInterval(function add() {

this.num++;

}, 1000);

}

var a = new addFunc();

위의 예제에는 add()함수는 this를 전역 객체로 정의하여 사용한다. 따라서 addFunc() 생성자의 this와는 다른 this이다.

아래의 예제는 비전역 변수에 할당하여 위의 문제를 해결을 하는 것이다.

function addFunc() {

var temp = this;

temp.num= 0;

setInterval(function add() {

temp.num++;

}, 1000);

}

var a = new addFunc();

위의 문제를 ES6부터는 arrow 함수를 이용하여 처리할 수 있다.

arrow 함수는 자신만의 this를 생성하지 않고, 감싸고 있는 컨텍스트의 this를 가져오므로 의도한대로의 기능을 가진다.

function addFunc() {

this.num

setInterval(() => {

this.num++;

}, 1000);

}

var a = new addFunc();

다시 말해 위의 arrow 함수를 이용한 뒤의 this는 addFunc()의 this와 같은 this이다.



2. Promise 객체

- 콜백이 중첩되어 사용되는 경우(하나의 작업을 콜백으로 처리한 뒤, 순차적으로 다음 작업을 진행하고자 하는 경우)에 사용할 수 있다.

- Promise 패턴을 사용하면 비동기 작업을 순차적으로 진행하거나, 병렬로 진행하는 등의 작업의 효율이 높아진다.

- 예외처리 구조가 잘되어 있으므로 오류처리에 대해 더 가시적인 처리가 가능하다.

- chrome 32 버전부터 native promise가 지원 가능하다.


아래는 Promise 패턴의 기본적인 예제이다.

var promiseFunc(param) {

return new Promise(function(resolve, reject) {

window.setTimeout(function() {

if (param) {

resolve("해결!");

} else {

reject(Error("실패!"));

}

}, 1000);

});

};

// 실행

promiseFunc(true)

.then(function(text) {

console.log(text);

}, function(error) {

console.error(error);

};

함수 선언은 var promiseFunc = function(param){...}; 의 형식으로 선언하여도 무관하다.

Promise 객체를 return으로 감싸는 이유는 Promise 객체 생성을 위한 것이다. 그리고 parameter를 익명함수로 가지고 있으며, resolve와 reject를 parameter로 가진다.


위의 과정을 볼 때, new Promise로 Promise가 생성되는 직후부터 resolve나 reject가 호출되기 전까지의 순간을 pending상태라고 한다.

이후, 비동기 작업을 마친 뒤, 결과물을 약속대로 전달할 수 있다면 첫번째 parameter로 주입되는 resolve 함수를 호출하고, 실패하면 두번째 parameter로 주입되는 reject함수를 호출한다.


아래는 Promise 객체의 네가지 상태를 정리한 것이다.

1. pending

: 아직 Promise를 수행중인 단계 (fullfilled 혹은 rejected 이전)

2. fullfilled

: Promise가 지켜진 상태

3. rejected

: Promise가 지켜지지 못한 상태

4. settled

: Promise 성공 여부와 무관하게 결론이 난 상태


예제에서 함수를 실행하는 부분을 보면 Promise 객체는 정상적으로 비동기화가 완료될 경우 then이라는 API가 존재하여 이를 이용한 결과를 실행한다. 위의 예제에서는 콘솔로그를 이용하여 '해결!'이라는 문구를 보여준다.

then API는 첫번째 parameter에는 성공시 호출할 함수를, 두번째 parameter에는 실패시 호출할 함수를 선언하고 Promise의 상태에 따라 수행한다.

작업 중 중간에 에러를 잡기 위해서는 catch API를 사용할 수 있다. catch API의 형태는 .catch(function(){......}) 와 같다.


* 여러개의 Promise 완료를 확인 해야하는 경우

var promise1 = new Promise(function(resolve, reject) {......});

var promise2 = new Promise(function(resolve, reject) {......});


Promise.all([promise1, promise2]).then(function(values) {

console.log("promise1과 promise2가 모두 완료됨.", values);

});

위와 같이 사용하면 promise1과 promise2를 처리하는데 시간차가 나더라도 두 promise가 모두 완료되어야 .all이 실행되어 확인이 가능하다.



3. 블록스코프

ES6부터 사용이 가능한 기능으로 기존에 사용하던 변수 var 외의 let 변수를 사용할 수 있다.

let 변수는 var와 다르게 호이스팅(hoisting)을 하지 않는다.

* 호이스팅(hoisting)

: 선언이 뒤에서 이루어진 경우, 선언된 변수나 함수가 Scope의 최상위에 위치하는 것을 의미하는 것으로 이로 인해 뒤에서 선언한 변수나 함수를 그 이전에 사용할 수 있도록 해준다.

따라서 변수가 선언된 이후부터 변수가 유효하고, 한 블록 내에서도 변수 선언 이전에는 에러처리가 된다.

같은 스코프에서 같은 이름의 변수를 다시 선언할 경우 에러처리가 된다. 하지만 변수 선언에서 문제가 되는 것이 아니라 실제로 해당 구문을 실행하면서 에러처리가 이루어지는 것이므로 같은 이름의 변수를 선언만 하고 사용하지 않을 경우 에러처리가 이루어지지 않는다.



4. 클래스 문법

class 키워드가 ES6에 추가되었지만 클래스기반 객체지향 개념이 추가된 것은 아니며, 프로토타입의 개념이다.

//클래스 선언

class Shape {

// 생성자

constructor(width, height) {

this.width = width;

this.height = height;

}

// 멤버메서드

getArea() {

return 0;

}

// static 메서드

static getType() {

return 'Shape';

}

}

위의 예제에서 class를 사용하는 방법을 확인할 수 있다.

클래스 선언을 할 때 위의 형태 대신 var Shape = class {......}의 형태로 선언할 수 있다. 이는 클래스도 함수이므로 함수표현식(function expression)으로 정의가 가능한 것이며, 클래스표현식(class expression)이라고도 한다.

+) getType()과 같이 static 메서드는 정의할 수 있으나 static 멤버를 정의할 수는 없다.


new Person();

class Person {......}

클래스 선언에서 유의할 점 중 하나는 클래스 선언에는 호이스팅(hoisting)이 적용되지 않는다는 것이다. 그러므로 위처럼 class 선언이 뒤에 나올 경우 Uncaught SyntaxError가 발생한다. 그리고 같은 이름의 클래스를 중복 선언할 경우 문법 에러가 발생한다.


class Rect extends Shape {

constructor(width, height) {

super(width, height);

}

getArea() {

return (this.width * this.height);

}

getType() {

return super.getType() + ' : Rect()';

}

}

또한 클래스를 이용하여 위와 같이 extends를 이용해 상속을 받을 수 있다.

생성자의 경우 super로 부모 참조가 가능하며, getArea()와 같이 부모의 메서드명과 같은 메서드가 있다면 부모의 메서드를 덮어쓸 수 있다. 그리고 getType()에서 확인 할 수 있듯이 멤머 메서드 내에서도 부모 인스턴스를 참조하여 사용할 수 있다.

 AngularJS를 제대로 알기 전 개념을 잡는 내용이다.


이전 게시글 클로저(Closures) 개념을 이해하고 난 뒤, 모듈패턴을 공부하면 더 쉬울 거 같다.


모듈패턴은 코드 관리 기법 중 하나로 객체 핸들링을 위한 방법 중 하나이다.

객체에 유효 범위를 줘서 private이나 public과 같은 접근 제한자와 같은 효과를 줄 수 있도록 캡슐화 할 때 사용한다.

그리고 모듈은 자체적으로 필요한 내부 변수 및 함수를 모두 가지고 있어야 성립한다.


아래의 예제는 모듈패턴 중 기본적인 형태를 가진 것이다.

var module = (function() {

var cnt = 0;

return {

incCnt : function() {

return cnt++;

},

decCnt : function() {

return cnt--;

}

}

})();


return이 되는 영역은 public으로 만들어 접근이 가능하고, return 문맥전의 공간은 클로저가 형성되면서 private 영역이 된다. 즉, 외부에서 직접적으로 cnt 변수에 접근하지 못하므로 cnt 변수는 private 영역에 있는 것과 같은 것이다.

모듈패턴이 클로저와 가장 다른 점은 모듈패턴의 return 값은 변수가 아닌 객체이며, 자동호출이 된다는 것이다.


AngularJS를 본격적으로 시작하기 전에 자바스크립트 패턴 이해에 필요한 개념 중 하나인 클로저(Closures)에 관한 내용을 정리


클로저는 외부 함수의 변수에 접근하기 위해 내부 함수를 사용하는 것이다.

클로저는 스코프체인에서 하나의 스코프를 생성해주는 개념으로 생각할 수도 있다.


여기서 스코프(Scope)를 알고 있어야 하는데, 간단하게 스코프(Scope)란 유효범위를 말하는 것으로, 변수 사용 가능 여부를 영역을 구분짓는 것으로 이해하면 쉽다. 그리고 자바스크립트에서는 함수만이 유효범위의 단위가 될 수 있다.

유효범위를 나타내는 스코프(Scope)가 프로퍼티(property)로 각 함수 객체 내에서 연결리스트 형식으로 구성되는데, 이를 스코프체인이라고 한다.

각각의 함수는 자신이 생성된 스코프체인을 참조하여 값을 가지게된다. 함수가 실행되면서 실행 컨텍스트가 생성되고, 이를 바탕으로 새로은 스코프체인을 만들게 되는 것이다. 이 개념을 생각하면 스코프체인 안에 다른 스코프 체인이 존재할 수도 있게 된다.


다시 클로저로 돌아가서.

내부함수는 외부함수의 변수도 접근이 가능하지만 파라미터 값으로도 접근이 가능하다. 단, 배열과 같은 객체에는 접근이 불가능하다. 따라서 클로저는 이런 특징을 이용하여 내부함수로 외부함수를 활용하는 방법이다.


아래에 간단한 예제를 확인해보도록 하자.


function outer() {

var cnt = 0;                                        → ①

var inner = function() {                        → 

return cnt++;

}

return inner;                                       → 

}


var inc = outer();                                     → 


inc();        // cnt === 1                            → 

inc();        // cnt === 2


위의 예제가 클로저를 알기 위한 가장 간단하고 대표적인 예제이다.

①은 outer 함수의 로컬(local) 변수이다. 변수 앞에 var는 변수를 선언하여 지역변수로 사용할 때 사용이 되며, 선언된 위치에 따라 변수의 스코프(scope)를 예측할 수 있다. 예를 들어 함수 내에서 var를 이용하여 변수를 선언해 사용하면 해당 변수의 사용 범위는 함수 내이다. 하지만 var가 없을 경우 전역변수로 사용할 수 있다.

②는 outer 함수의 로컬(local) 함수이다. 해당 함수의 경우 함수 안에 존재하는 함수이므로 외부에서 바로 접근이 불가능하며, 외부 함수로 우선 접근하여 내부 함수로 접근이 가능하다.

③에서 outer 함수 결과를 리턴한다. 리턴 값이 존재하지 않는 클로저(Closures)도 존재한다.

④에서 outer 함수를 호출한다. outer 함수를 호출할 경우 ③에서 리턴 된 함수가 ④에서 선언한 변수 inc에 저장된다.

⑤에서는 inc에 저장된 함수의 내부 함수인 inner 함수를 호출하여 접근한다.


위의 예제를 이용할 경우 outer 함수를 변수로 선언하여 사용할 때, 해당 변수를 이용하면 이전에 사용했던 cnt 변수에 계속 접근이 가능하다. 또한 inner 함수를 이용하여 변수 조작도 가능하다.

일반적인 스코프(scope)의 개념에서 볼 때, ④, ⑤와 같이 outer 함수 외부에서 함수의 로컬(local) 변수인 cnt로 접근하여 해당 변수의 값을 계속 가지고 있으면서 사용하기란 어렵다. 하지만 위의 예제와 같이 클로저(Closures) 개념을 사용하면 private 개념 적용이 가능하다.


 정리 내용.

특징 

1. 클로저는 function 안에 function이 존재할 때 생성된다.
2. 함수가 정의된 스코프(scope) 이외의 곳에서 사용될 때, private 처럼 사용이 가능하다.
3. 전역변수 사용을 억제하고 변수간의 충돌을 막을 수 있다. 이로인해 이벤트, 애니메이션에서 효과적으로 함수 사용이 가능하다.


단점

1. 메모리를 소모한다.
2. 스코프(scope) 생성에 따른 퍼포먼스 손해가 있다.
3. 직관적인 이해가 어려워 정확한 주석이나 문서와 같은 내용으로 정리를 해두는 것이 좋다.


+ Recent posts