[英]How can I factor a closure out of an outer function to reuse said closure in different contexts?
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
}
Uppon單擊btn1 , result1中顯示“hello”。
Uppon點擊btn2 , result2中顯示“YO”。
現在,您可能已經注意到,兩個handleEvent函數完全相同。 我想要實現的是類似的東西。
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return handleEvent;
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return handleEvent;
}
function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
}
但這當然不會起作用,因為handleEvent函數沒有在say和shout函數中聲明; 因此, 說和容器將不會被定義。
我曾嘗試用bind()的玩弄,並宣布說 , 集裝箱在此的發言權和呼喊函數中:
function say(word) {
this.saying = word;
this.container = document.getElementById('result1');
return handleEvent.bind(this);
}
function shout(word) {
this.saying = word.toUpperCase();
this.container = document.getElementById('result2');
return handleEvent.bind(this);
}
function handleEvent() {
var text = document.createTextNode(this.saying);
this.container.innerHTML = '';
this.container.appendChild(text);
}
但這也不起作用。
謝謝!
您不能在不同的上下文中重用閉包,因為根據javascript中的定義,閉包是一個綁定到其父上下文的內部函數。
但是,您可以提取函數體,以便在不同的上下文中重用它:
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function saySomething(context, saying) {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return function handleEvent() {
saySomething(context, saying);
};
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return function handleEvent() {
saySomething(context, saying);
};
}
或者如果你想使用bind:
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function saySomething(context, saying) {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return saySomething.bind(undefined, context, saying);
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return saySomething.bind(undefined, context, saying);
}
如果您創建了要綁定的新對象,則綁定應該有效,而不是使用this
:
function say(word) {
return handleEvent.bind({
saying: word,
container: document.getElementById('result1')
});
}
function shout(word) {
return handleEvent.bind({
saying: word.toUpperCase(),
container: document.getElementById('result2')
});
}
但是,你仍然可以通過正常的閉包來解決這個問題:
function say(word) {
return makeHandleEvent(word, 'result1');
}
function shout(word) {
return makeHandleEvent(word.toUpperCase(), 'result2');
}
function makeHandleEvent(saying, id) {
var container = document.getElementById(id);
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.