by chitacan
자신의 범위 밖에 있는 변수들에 접근할 수 있는 코드블록
외부에서 value 값에 접근할 수 없게 만들기
var myObject = function () {
var value = 0;
var what = 0;
return {
increment: function(inc) {
value += typeof inc === 'number' ? inc : 1;
what += 1;
},
getValue: function() {
return value;
}
}
}();
myObject.increment(3);
myObject.getValue();
Run this code
var fade = function(node) {
var level = 1;
var step = function() {
var hex = level.toString(16);
node.css('color', '#' + hex + 'FFFF' + hex);
if (level < 15) {
level += 1;
setTimeout(step, 100);
}
};
setTimeout(step, 100);
}
fade($('#closure-usage'));
Run this code
나쁜 예제
var addHandlers = function(nodes) {
var i;
for (i = 0 ; i < nodes.length ; i += 1) {
nodes[i].onclick = function(e) {
alert(i);
}
}
}
addHandlers($('#closure-bad').children());
더 나은 예제
var addHandlers = function(nodes) {
var i;
for (i = 0 ; i < nodes.length ; i += 1) {
nodes[i].onclick = function(i) {
return function(e) {
alert(i)
}
}(i);
}
}
addHandlers($('#closure-good').children());
내부의 상태, 구현을 숨기고 인터페이스만 제공하는 함수, 객체
함수 내에서만 사용하고 싶은 객체, 어떻게 저장하면 좋을까??
함수에 사용할 객체를 함수내부에 두고, 클로저를 만들자
Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
}
String.method('deentityify', function() {
var entity = {
quot: '"',
lt: '<',
qt: '>'
};
return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}
);
};
}());
'<">'.deentityify();
모듈 패턴을 활용한 안전한 객체 생성
var serial_maker = function() {
var prefix = 0;
var seq = 0;
return {
set_prefix : function(p) {
prefix = String(p);
},
set_seq : function(s) {
seq = s;
},
gensym : function() {
var result = prefix + seq;
seq += 1;
return result;
}
};
};
var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
seqer.gensym();
함수와 인수를 결합해 새로운 함수를 만들 수 있는 패턴
Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
}
Function.method('curry', function() {
var slice = Array.prototype.slice;
var args = slice.apply(arguments);
var that = this;
return function() {
return that.apply(null, args.concat(slice.apply(arguments)));
}
});
var add = function(a, b) {
return a + b;
}
var add1 = add.curry(1);
add1(7);
이전 연산결과를 저장하는 최적화 기법
var fibo = function(n) {
return n < 2 ? n : fibo(n-1) + fibo(n-2);
};
for (var i = 0 ; i <= 10; i += 1) {
fibo(i);
}
호출횟수가 줄었다는데, 어떻게 확인하지??
var fibo = function() {
var memo = [0,1];
var fib = function(n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}();
for (var i = 0 ; i <= 10; i += 1) {
fibo(i);
}
prototype closure inheritance