[英]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 clicking on btn1 , "hello" is displayed in result1 . Uppon单击btn1 , result1中显示“hello”。
Uppon clicking on btn2 , "YO" is displayed in result2 . Uppon点击btn2 , result2中显示“YO”。
Now, as you may have noticed, the two handleEvent functions are exactly the same. 现在,您可能已经注意到,两个handleEvent函数完全相同。 What I want to achieve is something like.
我想要实现的是类似的东西。
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);
}
But that of course will not work as the handleEvent function is not declared inside the say and shout functions; 但这当然不会起作用,因为handleEvent函数没有在say和shout函数中声明; thus, saying and container will not be defined.
因此, 说和容器将不会被定义。
I have tried playing around with bind() and declare saying and container on this inside the say and shout functions : 我曾尝试用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);
}
But that didn't work either. 但这也不起作用。
Thank you! 谢谢!
You cannot reuse a closure in a different context, because by definition in javascript a closure is an inner function which is bound to the context of its parent. 您不能在不同的上下文中重用闭包,因为根据javascript中的定义,闭包是一个绑定到其父上下文的内部函数。
You can however extract your function body in order to reuse it in different contexts: 但是,您可以提取函数体,以便在不同的上下文中重用它:
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);
};
}
Or if you want to use bind: 或者如果你想使用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);
}
Binding should have worked if you had created new objects to be bound to, instead of using this
: 如果您创建了要绑定的新对象,则绑定应该有效,而不是使用
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')
});
}
However, you still can solve this with a normal closure: 但是,你仍然可以通过正常的闭包来解决这个问题:
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.