以函数式方式重构 JS 代码——闭包
Refactoring JS code in a functional way - closures
我有以下重复代码,用于在满足特定条件时突出显示 html/css 代码的一部分。即,当我对select三个元素进行布局时。因为,selection 的顺序无关紧要,我必须重复代码三次,为每个元素创建侦听器。
因此,我想重构为更实用的风格,如闭包。
for (var m=0; m < selectedDessert.length; m++){
selectedDessert[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
selected[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
selectedDrink[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
};
我想在这些行中重构他:
let combinedVar = buyImages.length + buyImagesDrink.length + buyImagesDessert.length;
var funcOrder = function(selectVar) {
let selectedVar = selectVar;
selectVar[i].addEventListener("click", function(){
if (combinedVar === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "Fechar pedido";
}
});
};
var pSelectedDessert = funcOrder(selectedDessert);
var pSelectedDrink = funcOrder(selectedDrink);
var pSelected = funcOrder(selected);
for (var i = 0; i < selected.length; i++) {
pSelectedDessert();
pSelectedDrink();
pSelected();
}
Error:
highlight-all.js:29 Uncaught TypeError: Cannot read property 'addEventListener' of undefined
at funcOrder (highlight-all.js:29)
at highlight-all.js:37
Error-line:
selectVar[i].addEventListener("click", function(){
问题是:我如何将变量传递给此函数,因为它尚未定义(执行不同)。
无需使用闭包或尝试函数式方法(使用 dom 和响应事件无论如何都需要命令式风格)。
您可以做的第一个简化是使用命名函数,而不是重复三次相同的函数表达式 - 它是完全相同的代码,甚至不依赖于具有不同值的闭包变量。
function handleClick() {
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3) {
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}
}
for (var m=0; m < selectedDessert.length; m++) {
selectedDessert[m].addEventListener("click", handleClick);
selected[m].addEventListener("click", handleClick);
selectedDrink[m].addEventListener("click", handleClick);
}
我有以下重复代码,用于在满足特定条件时突出显示 html/css 代码的一部分。即,当我对select三个元素进行布局时。因为,selection 的顺序无关紧要,我必须重复代码三次,为每个元素创建侦听器。
因此,我想重构为更实用的风格,如闭包。
for (var m=0; m < selectedDessert.length; m++){
selectedDessert[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
selected[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
selectedDrink[m].addEventListener("click", function(){
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}});
};
我想在这些行中重构他:
let combinedVar = buyImages.length + buyImagesDrink.length + buyImagesDessert.length;
var funcOrder = function(selectVar) {
let selectedVar = selectVar;
selectVar[i].addEventListener("click", function(){
if (combinedVar === 3){
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "Fechar pedido";
}
});
};
var pSelectedDessert = funcOrder(selectedDessert);
var pSelectedDrink = funcOrder(selectedDrink);
var pSelected = funcOrder(selected);
for (var i = 0; i < selected.length; i++) {
pSelectedDessert();
pSelectedDrink();
pSelected();
}
Error:
highlight-all.js:29 Uncaught TypeError: Cannot read property 'addEventListener' of undefined
at funcOrder (highlight-all.js:29)
at highlight-all.js:37
Error-line:
selectVar[i].addEventListener("click", function(){
问题是:我如何将变量传递给此函数,因为它尚未定义(执行不同)。
无需使用闭包或尝试函数式方法(使用 dom 和响应事件无论如何都需要命令式风格)。
您可以做的第一个简化是使用命名函数,而不是重复三次相同的函数表达式 - 它是完全相同的代码,甚至不依赖于具有不同值的闭包变量。
function handleClick() {
if (buyImages.length + buyImagesDrink.length + buyImagesDessert.length === 3) {
footerStyle[0].classList.add("order");
footerStyleSpan.innerHTML = "string";
}
}
for (var m=0; m < selectedDessert.length; m++) {
selectedDessert[m].addEventListener("click", handleClick);
selected[m].addEventListener("click", handleClick);
selectedDrink[m].addEventListener("click", handleClick);
}