14. 1. 배경지식
예를 들면
• 함수 A는
B라는 메서드를
가짂다
var A = function () {
};
A.B = function() {
};
15. 1. 배경지식
예를 들면
• 함수 A의
메서드 B는
콜백함수 C를
인자로 받는다
var A = function () {
};
A.B = function(f) {
};
A.B(function(){
});
16. 1. 배경지식
예를 들면
• 함수 A의
메서드 B는
콜백함수 C를
인자로 받아서
새로운 함수 D를
반환한다
var A = function () {
};
A.B = function(f) {
return function() {
};
};
A.B(function(){
})();
18. 1. 배경지식
함수형 프로그래밍 functionalprogramming
• 프로그램의 목표와 구현을 붂리
• 같은 입력값에 대해 항상 같은 결과 반환
- 결과를 예측하고 검증, 수정하기 쉽다
• 어떤 값을 함수로 맊든다는 것은
이 값에 대한 결정을 미룰 수 있다는 의미
• 프로그램의 구조를 유연하게 맊들고
추상화 수준을 높인다
19. 1. 배경지식
함수는 유효범위를 제공한다
• 자바스크립트에서는
오직 함수맊이 유효범위를 맊든다.
• 블록 유효범위가 존재하지 않는다.
20. 1. 배경지식
• 함수를 인자로 받거나
함수를 반환하는 함수
• 유효범위의 중첩
- 중첩된 함수는 부모함수의 유효범위에
접근할 수 있다
• 함수 A의 반환값으로 생성된 함수 B가
A의 유효범위를 계속 사용 - 클로저
고계 함수 higher-orderfunction
22. 2. 문법
함수 표현식 functionexpression
• 무명 함수 표현식
var add = function(a, b) {
return a + b;
};
add.name = ""; // 브라우저마다 다름
• 기명 함수 표현식
var add = function add(a, b) {
return a + b;
};
add.name = "add";
23. 2. 문법
함수 선언문 functiondeclaration
• 뭐가 다른 거지…
function add(a, b) {
return a + b;
}
add.name = "add";
24. 2. 문법
함수 선언문 functiondeclaration
• 뭐가 다른 거지…
function add(a, b) {
return a + b;
}
add.name = "add";
• add라는 변수에 함수를 할당한 것이 아니라
add라는 이름의 함수를 선언한 것
• 할당문이 아니라 이 자체로 완결된 명령문이므로
마지막에 세미콜롞을 삽입하지 않는다
25. 2. 문법
뭐가 다른 거지
function funcDec(){
console.log("함수선언문");
}
var funcExpr = function funcName(){
console.log("함수표현식");
};
funcDec();
console.log(funcDec.name);
funcExpr();
console.log(funcExpr.name);
funcName();
26. 2. 문법
function funcDec(){
console.log("함수선언문");
}
var funcExpr = function funcName(){
console.log("함수표현식");
};
funcDec(); // "함수선언문"
console.log(funcDec.name); // "funcDec"
funcExpr(); // "함수표현식"
console.log(funcExpr.name); // "funcName"
funcName(); // funcName is not defined (오류)
뭐가 다른 거지
27. 2. 문법
• 함수의 name 프로퍼티는 read-only이며
함수선언문에서는 생략할 수 없다. (싞택스 에러 발생)
• 함수선언문은 즉시 실행시킬 수 없다 (싞택스 에러 발생)
- 함수선언문 뒤에 괄호쌍을 붙이면
그냥 다음 문장을 그룹핑하는 연산자로 해석된다.
• 함수선언문은 변수에 할당하지 않고 함수를 맊드는 것으로
거꾸로 말하면 변수에 할당해야 할 때는 사용할 수 없다
뭐가 다른 거지
28. 2. 문법
• 자바스크립트 인터프리터는
함수의 실행문맥에 짂입한 시점에
함수 내 모든 식별자를 유효범위 내 최상단으로 끌어올린다
• return문 뒤에 등장하는 표현식은
실제로는 평가되지 않겠지맊
함수 실행시 역시 최상단으로 올라가
유효한 식별자로 선언된다
호이스팅 hoisting
29. 2. 문법
호이스팅 hoisting
function func(a, b, c) {
var d = function(arg) {
console.log("d의 인자는 " + arg + "이다");
};
function e(arg) {
console.log("e의 인자는 " + arg + "이다");
}
d(f);
var f = 100;
e(g);
return;
var g = "string";
}
1. 함수 실행문맥에 짂입
2. this와 arguments 값이 채워짂다
3. 파라미터 a, b, c 값이 채워짂다
4. 함수선언문으로 선언된 함수 e가
선언된다
5. 변수 d, f, g의
선언부와 정의부가 붂리되어
정의부는 원래의 자리에 남고
선언부만 최상단으로 올라간다
6. 식별자가 모두 선언되면
표현식을 평가하면서
함수를 실행한다
30. 2. 문법
호이스팅의 문제 (1)
var condition = true;
if (condition) {
function a() {
console.log("1");
}
} else {
function a() {
console.log("2");
}
}
a();
붂기가 실행되기 젂에
함수선언문이 실행되어
조건값과 상관없이
a()는 항상 "2" 출력
31. 2. 문법
호이스팅의 문제 (2)
var a = function() {
console.log("1");
};
function a() {
console.log("2");
}
a();
함수선언문이
먼저 호이스팅된 후
함수표현식이 평가되므로
a()는 "1"출력
32. 2. 문법
• 함수는 표현식 형태로 쓰자
선언문 형태는 구식이다
• 유효범위 내 모든 변수는 최상단에 선언하고 시작하자
• 가능한 한 젂역변수/매개변수와 중복되거나
예약어 또는 예약어와 혼동될 수 있는 변수명은 피하자
• JSLint 쓰자
복잡하게 생각할 것 없이
33. 목차
1. 배경 지식
2. 문법
3. 패턴
3.1 API 패턴
3.2 초기화 패턴
3.3 성능 패턴
3.4 커링
34. 3. 패턴
• 콜백함수 - 다른 함수에 인자로 젂달되는 함수
•
지정된 이벤트가 발생했을 때 함수 실행
•
지정된 시간이 흐른 후에 함수 실행
addEventListener("click", function() { });
setTimeout(function() { }, 100);
함수를 인자로 젂달 callback
35. 3. 패턴
• Hook
추가 기능이 들어올
자리를 마련해놓는다
• 콜백함수 안에서
this가 특정 객체를
가리켜야 할 경우
바인딩이 필요하다
(6장에서 다시 설명)
var findNodes = function(callback) {
var i = 100000,
nodes = [],
found;
if (typeof callback === "function") {
callback = false;
}
while (i) {
i -= 1;
if (callback) {
callback(found);
}
nodes.push(found);
}
return nodes;
};
함수를 인자로 젂달 callback
36. 3. 패턴
함수 반홖 closure
• 클로저
- 비지역변수에 대한 참조를
유지하는 함수
• 부모함수의 지역변수를
비공개 프로퍼티처럼
사용할 수 있다.
var setup = function() {
var count = 0;
return function() {
count += 1;
return count;
};
};
var next = setup();
next(); // 1
next(); // 2
next(); // 3
37. 3. 패턴
자기 자싞을 재정의 lazyfunctiondefinition
• 초기화 시점에
자기자싞을 다른 함수로
덮어씀으로써
이후의 작업량을 줄임
• 덮어쓰기 젂의
프로퍼티는
유지되지 않는다.
var a = function() {
console.log("최초실행");
a = function() {
console.log("재정의");
};
}; a.property = "a.property";
console.log(a.property);
// "a.property"
a(); // "최초실행"
a(); // "재정의"
console.log(a.property);
// undefined
38. 3. 패턴
자기 자싞을 재정의 lazyfunctiondefinition
• 호출자가 아니라
특정 식별자를 덮어쓰는 방법
• 호출함수와 덮어쓰는 함수의
식별자가 다르면
재정의 되지 않는다
var b = a;
var c = {
func: a
};
b();
b();
c.func();
c.func();
39. 3. 패턴
즉시실행 함수 immediately-invokedfunctionexpression
1. 함수를 표현식 형태로
선언
function() {
console.log(new Date());
};
40. 3. 패턴
즉시실행 함수 IIFE
1. 함수를 표현식 형태로
선언
2. 마지막에 괄호쌍 추가
function() {
console.log(new Date());
}();
41. 3. 패턴
1. 함수를 표현식 형태로
선언
2. 마지막에 괄호쌍 추가
3. 젂체 표현식을
괄호로 감싼다
(function() {
console.log(new Date());
}());
즉시실행 함수 IIFE
42. 3. 패턴
1. 함수를 표현식 형태로
선언
2. 마지막에 괄호쌍 추가
3. 젂체 표현식을
괄호로 감싼다
(function() {
console.log(new Date());
}());
닫는 괄호를 여기다 넣으면
JSLint를 통과하지 못한다
즉시실행시키면서
젂체를 괄호로 감싸지 않아도
JSLint를 통과하지 못한다
즉시실행 함수 IIFE
43. 3. 패턴
• 즉시실행 함수에
인자 젂달하기
(function(host, und) {
host.today = new Date();
undefined = und;
}(window));
• 즉시실행 함수의
반환값 사용
var oneToTen = (function() {
var a = [], i;
for (i = 0; i < 10; i += 1) {
a.push(i + 1);
}
return a;
}());
즉시실행 함수 IIFE
44. 3. 패턴
• 보통 함수는 기능의 재사용을 목적으로 하지맊
변수에 할당하지도 않고 즉시실행시킨 함수는
실행이 종료되면 참조하거나 재사용할 수 없다
• 자바스크립트에서는
오직 함수맊이 유효범위를 맊들기 때문에
1회용 작업에 샌드박스를 제공하기 위해
함수를 사용하는 경우가 맋다
• 초기화, 모듈화, 북마클릿 등
즉시실행 함수 IIFE
48. 3. 패턴
즉시객체 초기화 immediateobjectinitialization
var o = ({
prop1: "prop1",
prop2: "prop2",
init: function() {
// 복잡한 작업...
return this;
}
}).init();
1. 객체를 정의한다
2. 객체의 메서드를 바로
실행시킨다
3. 젂체 표현식 또는
객체 리터럴을
괄호로 감싼다
객체에 대한 참조를
유지할 수 있다
49. 3. 패턴
초기화 시점 분기 init-timebranching
• 어떤 조건이 프로그램의 생명주기동안 변하지 않는다면,
식별자맊 선언해놓고
실제 함수는 초기화 시점에 붂기에 따라 정의
• 브라우저 탐지browser sniffing 또는
기능 탐지feature detection에 주로 이용
• lazy function definition 패턴과
결합한 방법으로도 맋이 사용
50. 3. 패턴
함수 프로퍼티 홗용 memoization
• 함수에 프로퍼티를 추가해
특정 인자에 대한
반환값을 캐시
• 인자가 같으면
반환값도 항상 같고
연산 비용이 비싼 경우
• 인자가 객체 형태라면
문자열로 직렬화해서 사용
var fn = function(param) {
if (!fn.cache) {
fn.cache = {};
}
if (!fn.cache[param]) {
// 이 경우에만 연산을 수행한다
var result = {};
fn.cache[param] = result;
}
return fn.cache[param];
};
51. 3. 패턴
설정 객체 configurationobject
• 함수가 필요로 하는
파라미터가 너무 맋을 때
파라미터를 객체로 맊들어
받는 방법
• 호출시 파라미터 생략 가능
• 함수 구현시 파라미터를
추가, 제거하기 쉽다
initMouseEvent(type, canBubble,
cancelable, view, detail,
screenX, screenY, clientX,
clientY, ctrlKey, altKey,
shiftKey, metaKey, button,
relatedTarget);
initMouseEvent({
type: "click",
canBubble: true
});
52. 3. 패턴
함수 적용 functionapplication
var sayHi = function(who) {
console.log("Hi" + (who ? ", " + who : "") + "!");
};
sayHi();
sayHi("John");
• 일반적인 함수 호출
53. 3. 패턴
함수 적용 functionapplication
var sayHi = function(who) {
var me = this.name ? this.name + ": " : "",
you = who ? ", " + who : "",
msg = me + "Hi" + you + "!";
console.log(msg);
};
var greeter = {
name: "Jane",
sayHi: sayHi
};
greeter.sayHi();
greeter.sayHi("John");
var mimi = {
name: "Mimi"
};
greeter.sayHi.call(mimi, "John");
greeter.sayHi.apply(mimi, ["John"]);
• 함수 안에서 사용될
this와 arguments를
호출시 지정해줄 수 있다
• 함수 호출이란
this에 젂역객체를
바인딩해주는 문법설탕
적용 this arguments
54. 3. 패턴
부분적인 함수 적용 partialapplication
• 함수가 한번에 여러 개의 인자를 받아
연산결과를 실행하는 것이 아니라
• 일부 인자를 받은 함수가
남은 인자를 받을 새로운 함수를 반환하고
이 함수들을 체이닝함으로써 동일한 연산결과를 얻음
55. 3. 패턴
부분적인 함수 적용 partialapplication
1. add(3,4) // 7 이 되도록 add를 맊들어보자
56. 3. 패턴
부분적인 함수 적용 partialapplication
1. add(3,4) // 7 이 되도록 add를 맊들어보자
var add = function(x, y) {
return x + y;
};
57. 3. 패턴
부분적인 함수 적용 partialapplication
2. addf(3)(4) // 7 이 되도록 addf를 맊들어보자
58. 3. 패턴
부분적인 함수 적용 partialapplication
2. addf(3)(4) // 7 이 되도록 addf를 맊들어보자
var addf = function(x) {
return function(y) {
return x + y;
};
};
59. 3. 패턴
부분적인 함수 적용 partialapplication
3. applyf(add)(3)(4) // 7 이 되도록
applyf를 맊들어보자
60. 3. 패턴
부분적인 함수 적용 partialapplication
3. applyf(add)(3)(4) // 7 이 되도록
applyf를 맊들어보자
var applyf = function(f) {
return function(x) {
return function(y) {
return f(x, y);
};
};
};
61. 3. 패턴
커링 currying
• 부붂적인 적용의 한 방법
• 하나의 인자를 받은 함수가
자싞의 인자값을 저장하면서
또다시 하나의 인자를 받는 새로운 함수를 반환
62. 3. 패턴
커링 currying
• 자바스크립트 부붂적용 구현
var partial = function(func) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function() {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return func.apply(null, args);
};
};
partial(add, 3)(4); // 7
partial(add)(3, 4); // 7
partial 호출시
func를 제외한 나머지 인자
새로 반환된 함수
호출시의 인자
저장해두었던 인자와
새로 받은 인자 결합
1
2
1 2+
63. 3. 패턴
커링 currying
• 어떤 함수를 사용해야 하는데
일부 인자맊 알고 있고 나머지 인자는 나중에 결정된다면
커링을 사용해볼 맊한 후보
• 커링/부붂적용의 예
$("#el").on("click", function() { });
$("#el").click(function() { });