글
클로져 활용법
function makerSize(size){
return function(){
document.body.style.fontSize = size + 'px';
};
}
var size12 = makerSize(12); var size14 = makerSize(14); var size16 = makerSize(16);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
<a href="#" id="size-12"> 12 </a>
<a href="#" id="size-14"> 14 </a>
<a href="#" id="size-16"> 16 </a>
클로져 : 두개의 이루어진 특별한 오브젝트이다.
첫 번째는 함수이고 두 번째는 그 함수가 만들어진 환경이다.
그 함수가 만들어진 환경을 함수가 만들어질 때 사용할 수 있었던 변수들로 이루어진다.
function makefunc(){
var name = "Mozilla";
function displayName(){
alert(name);
}
return displayName;
}
이 경우에는 displayName 함수와 "Mozilla" 문자열을 포함하는 클로져이다.
var counter = (function(){
var privateCounter = 0;
function changeBy(val){
privateCounter += val;
}
return { increment : function(){ changeBy(1); },
decrement : function(){ changeBy(-1); },
value : function(){ return privateCounter; } };
});
자주 하는 실수 : 클로져
<p id="help"> Help </p>
<p> E - mail : <input type='text' id='email' name='email'> </p>
<p> Name : <input type='text' id='name' name='name'> </p>
<p> Age : <input type='text' id='age' name='age'> </p>
function showHelp(help){
document.getElementById('help').innerHTML = help;
}
function setupHelp(){
var helpText = [{'id' : 'email', 'help' : 'e-mail'}, {'id' : 'name', 'help' : 'name'}, {'id' : 'age', 'help' : 'age'}];
for(var i=0; i<helpText.length; i++){
var item = helpText[i];
document.getElementById(item.id).onfocus = function(){ showHelp(item.Help); }
}
}
setupHelp();
이 코드는 제대로 실행되지 않는다.
이유는 onfocus 이벤트에 지정한 함수가 클로져라는 것이다.
이 클로져는 함수 본체와 setupHelp 함수의 스코프로 이루어져 있다.
세개의 클로져가 만들어졌지만 각 클로져는 하나의 환경을 공유한다.
반복문이 끝나고 onfocus 콜백이 실행될때, 콜백의 환경에서 item 변수는 (세개의 클로져가 공유한다.)
helpText 리스트의 마지막 요소를 가리키고 있을 것이다.
여러개의 클로져를 이용해서 문제를 해결 할 수 있다.
function showHelp(help){
document.getElementById('help').innerHTML = help;
}
function makeHelpCallback(help){
return function(){ showHelp(help); };
}
function setupHelp(){
for(var i=0; i<helpText.length; i++){
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
setupHelp();
성능 관련해서
클로져가 필요하지 않은 작업인데도 함수 안에 함수를 만드는 것은 스크립트 처리 속도와 메모리 사용량 모두에서 현명한 선택이 아니다.
예를 들면 새로운 오브젝트나 클래스를 만들 때 오브젝트 생성자에 메소드를 정의하는 것 보다 오브젝트의 프로토타입에 정의하는 것이 좋다.
오브젝트 생성자에 정의하게 되면 생성자가 불릴 때 마다 메소드가 새로 할당되기 때문이다.
function MyObject(name, message){
this.name = name;
this.message = message;
this.getName = function(){ return this.name; };
this.getMessage = function(){ return this.message; };
}
||
V
function MyObject(name, message){
this.name = name;
this.message = message;
}
MyObject.prototype = {
getName : function(){
return this.name;
},
getMessage : function(){
return this.message;
}
};
or
function MyObject(name, message){
this.name = name;
this.message = message;
}
MyObject.prototype.getName = function(){ return this.name; };
MyObject.prototype.getMessage = function(){ return this.message; };
위의 두 예제는 상속된 속성은 모든 오브젝트에서 사용될 수 있고 메소드 정의가 오브젝트 생성될 때마다 일어나지 않는다.
* 글로벌 변수는 delete로 지울 수 없다.
ex) // global variable;
var a = 1; // Don't Delete is set
delete a; // false
a; // 1
// normal function;
function f(){} // Don't Delete is Set
delete f; // false
type of f; // "function"
// ressigning doesn't help;
f = 1;
delete f; // false
f; // 1
명기된 속성은 지울 수 있다.
var obj = {x : 1};
obj.y = 2;
delete obj.x; //true
delete obj.y; // true
obj.x; // undefined
obj.y; // undefined
'J > Javascript' 카테고리의 다른 글
수정된 정보를 다시 부모창으로 넘겨주기, 부모에서 자식 창으로 넘겨주기 (0) | 2014.03.18 |
---|---|
Form안 Json 만들기 (0) | 2014.03.18 |
javascript arguments를 array로 변환하기 (0) | 2014.03.16 |
JavaScript - Prototype's delay() Function (0) | 2014.03.16 |
javascript 파일 저장하기 (0) | 2012.12.25 |