【问题标题】:Issue with local/global scope and NAN本地/全局范围和 NAN 问题
【发布时间】:2020-11-24 13:03:36
【问题描述】:

好的,所以我有以下代码来创建一个计算器:

const numbers = document.querySelector('.numbers')
const display = document.querySelector('.display')
const functions = document.querySelector('.functions')
const equalClear = document.querySelector('.equalClear')

numbers.addEventListener('click', e => {
    // selecting and adding nr to display
   if(e.target.innerHTML == '1'){
       display.innerHTML += '1';
   }else if (e.target.innerHTML == '2'){
       display.innerHTML += '2';
   }else if (e.target.innerHTML == '3'){
    display.innerHTML += '3';
}else if (e.target.innerHTML == '4'){
    display.innerHTML += '4';
}else if (e.target.innerHTML == '5'){
    display.innerHTML += '5';
}else if (e.target.innerHTML == '6'){
    display.innerHTML += '6';
}else if (e.target.innerHTML == '7'){
    display.innerHTML += '7';
}else if (e.target.innerHTML == '8'){
    display.innerHTML += '8';
}else if (e.target.innerHTML == '9'){
    display.innerHTML += '9';
}else if (e.target.innerHTML == '0'){
    display.innerHTML += '0';
}
});

functions.addEventListener('click', e => {
    // selecting a function and adding it to the display
    if(e.target.innerHTML == 'Add'){
        display.innerHTML += '+';
        functionVal = add();
    } else if(e.target.innerHTML == 'Subtract'){
        display.innerHTML += '-';
        functionVal = subtract();
    } else if(e.target.innerHTML == 'Multiply'){
        display.innerHTML += '*';
        functionVal = multiply()
    } else if(e.target.innerHTML == 'Divide'){
        display.innerHTML += '/';
        functionVal = divide();
    }else{
        display.innerHTML + 'Error'
    }
    numberVal = display.innerText; //creating variable with value of nr in display
    console.log(numberVal, "numberVal");
    console.log(functionVal, "functionVal");
});

equalClear.addEventListener('click', e => {
    if(e.target.innerHTML === 'Clear'){
        display.innerHTML = "";
    } 
    else if(e.target.innerHTML = '='){
    }
})

//functions for calculator

function add(variable1, variable2) {
    return variable1 + variable2;
};

function subtract(variable1, variable2) {
    return variable1 - variable2;
}

function multiply(variable1, variable2) {
    return variable1 * variable2;
};

function divide(variable1, variable2) {
    return variable1 / variable2;
}

// operation in calculator

function operate(operator, num1, num2){
   operate = operator, num1, num2;
}

operate(functionVal(numberVal,5))
console.log(operate, "this is an operation");

我在“functions.addEventListener”中定义了“functionVal”和“numberVal”。但是当我尝试在代码底部的“操作”函数中调用它们时,我发现“functionVal”和“numberVal”是未定义的。我知道这是因为它位于“functions.addEventListener”函数的本地范围内,并且我尝试在代码块之前为它们中的每一个添加一个“var”,以便为它们提供全局范围。但它不起作用,我有点疯狂地试图找出如何能够在我的“操作”函数中调用它们。

另外,当我在“functions.AddEventListener”的“console.log”中调用“functionVal”时,我知道“functionVal”是 NAN,我知道它不是“数字”,但它不应该显示实际我赋予它的价值的功能?我已经设置,如果你在 HTML 中按下“add”,“functionVal”的值就会变成我在代码底部定义的“add”函数。我不确定这里出了什么问题,因此非常感谢任何帮助。

在“操作”函数中,我给第二个参数值 5 只是为了测试,但一旦我能够解决问题,就会在显示中添加实际的“第二个数字”。

感谢您的帮助!

亲切的问候, 一个JS菜鸟

【问题讨论】:

    标签: javascript function scope nan addeventlistener


    【解决方案1】:

    好吧,一开始,这确实不好,为什么你要检查相等性(并为相同的类型使用=== 运算符):

    numbers.addEventListener('click', e => {
        // selecting and adding nr to display
       if(e.target.innerHTML == '1'){
           display.innerHTML += '1';
       }else if (e.target.innerHTML == '2'){
           display.innerHTML += '2';
       }else if (e.target.innerHTML == '3'){
        display.innerHTML += '3';
    }else if (e.target.innerHTML == '4'){
        display.innerHTML += '4';
    }else if (e.target.innerHTML == '5'){
        display.innerHTML += '5';
    }else if (e.target.innerHTML == '6'){
        display.innerHTML += '6';
    }else if (e.target.innerHTML == '7'){
        display.innerHTML += '7';
    }else if (e.target.innerHTML == '8'){
        display.innerHTML += '8';
    }else if (e.target.innerHTML == '9'){
        display.innerHTML += '9';
    }else if (e.target.innerHTML == '0'){
        display.innerHTML += '0';
    }
    });
    

    你可以这样改写:

    numbers.addEventListener('click', e => { 
        display.innerHTML += e.target.innerHTML;
    }
    

    如果我理解正确,numbers 必须是带有数字的按钮数组,但querySelector 只返回第一次出现,所以它只会返回第一个按钮。 您应该使用querySelectorAll 并像这样重写它:

    const numbersButtons = document.querySelectorAll('.numbers');
    // convert to array, because we can't iterate over querySelectorAll result
    Array.from(numbersButtons).forEach((button,index) => {
        button.addEventListener('click', e => {
            display.innerHTML += e.target.innerHTML;
        }
    });
    

    函数,概率,也必须是一个数组,你可以使代码更清晰,例如使用函数映射:

    const functionsMap = {
        '+': add,
        '-': subtract
        // and other functions..
    }
    

    然后这样称呼他们:

    // will return add function
    const targetFunc = functionsMap['+'];
    // call with parameters
    targetFunc(1,2);
    

    是的,当你这样做时:

     functionVal = divide();
    

    您不传递对函数的引用,而是执行它,因此functionVal 将存储函数执行的结果,是的,它将返回NaN,因为您在没有参数的情况下执行它,请在控制台中尝试:

    function add (a,b){return a + b}
    console.log(add());
    

    还有很多错误,我就不一一分析了,建议大家还是回到最开始,好好把握自己在做的事情。

    【讨论】:

    • 您好 Rostegg,感谢您的帮助!我将检查您所说的内容并修复我的代码。就一个问题。当我使用“numbers.addEventListener('click', e => { display.innerHTML += e.target.innerHTML; )}”并在数字之间单击时,我的“显示”会得到完整的“数字
      ”添加到它,将其包裹在实际的“数字 div”下方的一个大圆圈中。这就是我添加相等性的原因,因此它会排除数字按钮之外的点击。有没有办法从实际数字按钮之外的点击中排除要显示的附加值?感谢大家的帮助!
    • 您需要找到的不是父元素,而是所有按钮,此处示例:jsfiddle.net/p0xm469f
    • 感谢您再次检查,但问题仍然存在,当我在我的 js 文件中实现它并在我的实时服务器中运行它时,当我按下一个按钮时,“警报”会以正确的数字触发显示为“弹出窗口”并添加到“显示”中(到目前为止一切都很好)。但是,如果我在按钮之间按下,警报会显示“NAN”,然后它会将显示环绕在按钮下方的圆圈中,以使“数字”使它们无法使用。所以我想知道如何解决这个问题,我了解如何使用数组等,但问题是我的“显示”在使用它时会变形,这就是我使用相等性的原因。
    • 只需提供您项目的链接(github 或其他)
    • github.com/DojaCat/calculator.git 再次感谢您的检查!
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签