반응형
이 글은 JavaScript Patterns Build Better Applications with Coding and Design Patterns 책을 학습 후 중요 부분을 요약한 것입니다.
Background
- 자바스크립트의 함수는 일급 객체다.
- 함수는 유효범위를 갖는다.
- 함수는 다음과 같은 특징을 갖는 객체다.
- 프로그램 실행(런타임) 중에 동적으로 생성한다
- 변수에 할당할 수 있고, 다른 변수에 참조를 복사할 수 있고, 확장가능하고, 삭제할 수 있다.
- 다른 함수의 인자로 전달할 수 있고, 다른 함수의 반환 값이 될 수 있다.
- 프로퍼티와 메서드를 가질 수 있다.
- 자바스크립트에서 함수는 하나의 객체
- 자바스크립트는 중괄호
{}의 유효범위가 함수 내부를 제외하곤 없다.
용어
- 기명 함수 (named function expression)123
varadd =functionadd (a, b) {returna + b;}; - 무기명 함수 (unnamed function expression) & 함수 표현식 (function expression)123
varadd =function(a, b) {returna + b;}; - 함수 선언문 (function declaration)123
functionfoo() {// body}
콜백 패턴
- 함수는 객체이기 때문에 아래처럼 함수를 다른 함수에 콜백 형태로 전달할 수 있다.123456789
functionwriteCode (callback) {callback();}functionintroduceBugs () {// body...}writeCode(introduceBugs);// ! introduceBugs() 를 넘기게 되면 함수가 호출이 되므로 함수의 참조값만 넘긴다. - 대부분의 클라이언트 브라우저 프로그래밍은 event-driven 방식 :
Don't call us, we'll call you 아래는 타임아웃에 관한 안티패턴이다.
12345varthePlotThickens =function() {console.log('500ms later...');}setTimeout(thePlotThickens(), 500);// 안티패턴// setTimeout(thePlotThickens, 500) 처럼 함수 포인터만 넘겨줘야 한다.
함수 반환하기
- 함수 반환의 간단한 예123456789
varsetup =function() {alert(1);returnfunction() {alert(2);};};varmy = setup();// alert(1)my();// alert(2) - 함수 반환에서 사용되는 클로저의 예1234567891011
varsetup =function() {varcount = 0;returnfunction() {return(count += 1);};};varnext = setup();next();// 1next();// 2next();// 3
자기 자신을 정의하는 함수
- 새로운 함수로 자기 자신을 덮어쓰는 경우 : 어플리케이션 성능에 많은 도움이 된다12345678910
// Lazy Function Definition : 사용 시점 전까지 함수를 정의하지 않고 있다가, 호출된 이후에는 더 적게 일한다.varscareMe =function() {alert("Boo!");scareMe =function() {alert("Double boo!");};};scareMe();// Boo!scareMe();// Double Boo! - scareMe() 함수를 일급객체로 사용하는 예1234567891011121314151617
scareMe.property = "properly";varprank = scareMe;vvarspooky = {boo: scareMe;};prank();// Boo!prank();// Boo!console.log(prank.property);// "properly"spooky.boo();// Boo!spooky.boo();// Boo!console.log(spooky.boo.property);// "properly"scareMe();// Double Boo!scareMe();// Double Boo!console.log(scareMe.property);// undefined
즉시 실행 함수
- 즉시 실행함수는 선언됨과 동시에 실행된다. 자기 실행함수 라고도 한다.
- 즉시 실행함수의 패턴은 다음과 같다.
- 함수를 함수 표현식으로 선언한다 (var a = function(){}; 타입으로는 동작하지 않는다.)
- 함수 마지막에 괄호쌍을 추가한다.
- 전체 함수를 괄호로 감싼다.
- 즉시 실행함수는 코드 안의 모든 코드를 지역 유효범위로 감싸고, 어떤 변수도 전역 유효범위로 새어나가지 않게 한다.123456789
(function() {vardays = ["Sun", "Mon"];today =newDate();msg = "Today is" + days[today.getDay()];alert(msg);}());// days, today, msg 변수들의 범위는 모두 전역이 아니다. - 즉시 실행함수의 매개변수는 다음과 같이 전달한다.12345
(function(who, when) {console.log("I met " + who + " on " + when);}("Joe Black",newDate())); - 일반적으로 즉시 실행함수에는 매개변수를 많이 전달하지 않는게 코드 가독성에 도웅이 된다.
즉시 실행함수의 반환 값
다른 함수와 마찬가지로 즉시 실행함수도 값을 반환할 수 있고, 변수에 할당할 수 있다.
12345678910varresult = (function() {return2 + 2;}());vargetResult = (function() {varres = 2 + 2;returnfunction() {returnres;};}());- 장점과 사용방법 : 선언된 모든 변수는 스스로를 호출하는 함수의 지역변수가 되기 때문에, 임시 변수가 전역 공간을 어지럽힐까 걱정하지 않아아도 된다.
즉시 객체 초기화
아래 패턴은 객체가 생성된 즉시 객체를 초기화 한다.
1234567891011({maxWidth: 600.maxHeight: 400,gimmeMax :function() {returnthis.maxWidth + "x" +this.maxHeight;},init :function() {console.log(this.gimmeMax());}}).init();- 위 패턴의 장점은 초기화 하는 동안, 전역 네임스페이스를 보호할 수 있다.
- 위 패턴의 단점은 자바스크립트 compression 시에 즉시 실행 함수 패턴에 비해 효과적으로 압축하지 못할 수 있다. 왜냐하면 비공개 프로퍼티와 이름이 더 짧게 변경되지 않는 것이 compression 도구 관점에서는 안전하기 때문.
초기화 시점의 분기
- 초기화 시점의 분기(로드타임 분기)는 각각 브라우저의 기능을 확인하는 최적화 패턴이다.
아래 코드처럼 각 브라우저의 기능 지원범위를 확인할 수 있다.
1234567891011121314varutils = {addListener:function(el, type, fn) {if(typeofwindow.addEventListener ==='function') {el.addEventListener(type, fn,false);}elseif(typeofdocument.attachEvent ==='function') {el.attachEvent('on'+ type, fn);}else{el['on'+ type] = fn;}},removeListener:function(el, type, fn) {// ...}};- 브라우저의 기능은 독립적으로 변하기 때문에, 상기 코드로 초기화 시점 분기를 사용해 기능 지원여부를 판단한다.
설정 객체 패턴
- 설정 객체 패턴은 좀 더 깨끗한 API 를 제공하는 방법. 라이브러리나 reuse 컴포넌트를 만들 때 유용하다.
addPerson()이라는 함수를 만들 때, 인자수가 많아지면 다음과 같이addPerson("First Name", "Last Name", ...)함수 선언이 길어지므로 아래와 같은 패턴을 사용한다.123456addPerson(conf);varconf = {userName : "batman",first: "Bruce",last: "Wayne"};- 위 패턴의 장점은
- 매개변수와 순서를 기억할 필요가 없다.
- 선택적인 매개변수를 안전하게 생략이 가능하다.
- 매개변수 추가 제거가 편하다.
- 위 패턴의 단점은
- 매개변수의 이름을 기억해야한다.
- 프로퍼티의 이름은 압축되지 않는다.
커리 (Curry)
함수 적용
- 순수한 함수형 프로그래밍에서 함수는 호출된다고 표현하기 보다 적용된다고 표현한다.
- 자바스크립트에서도
Function.prototype.apply()를 이용하여 함수를 적용할 수 있다.1234567varsayHi =function(who) {return"Hello" + (who ? ", "+ who : "") + "!";};sayHi();// "Hello"sayHi("World");// "Hello, World"sayHi.apply(null, ["hello"]);// "Hello, hello!" - apply 의 첫 번째 매개변수가 null 이면 this 는 전역 객체를 가리킨다.12345678
varalien = {sayHi:function(who) {return"Hello" + (who ? ", " + who : "") + "!";}};alien.sayHi("world");// "Hello, world!"sayHi.apply(alien, ["humans"]);// "Hello, humans!" - 이 코드에서 sayHi() 내부의 this 는 alien 을 가리킨다. 앞선 예제의 this 는 전역 객체를 가리킨다.
call() 메서드 역시 apply() 메서드와 비슷하며, 함수의 매개변수가 하나일 때는 굳이 배열을 만들지 않고 아래와 같이 call() 을 이용한다.
12sayHi.apply(alien, ["humans"]);// "Hello, humans!"sayHi.call(alien, "humans");// "Hello, humans!"
반응형
'Programming > Javascript, jQuery' 카테고리의 다른 글
| Javascript 콜백함수 (0) | 2016.12.22 |
|---|---|
| Javascript 가변 인자 함수 만들기 (0) | 2016.12.22 |
| javascript 자바스크립트 클로저 (Closure) (0) | 2016.12.07 |
| jQuery 요소 있는지 검사 (0) | 2016.12.07 |
| jQuery Selectors > :empty 빈 요소 찾기 (0) | 2016.12.07 |