JavaScript函数修改全局变量后复用函数时值重置问题
问题根源
核心原因是JavaScript中原始类型参数按值传递,三个直接问题导致变量修改无法持久:
- 函数参数列表中定义的
conto是函数作用域内的局部形参,和全局声明的conto不是同一个变量。每次调用函数传参时,只是把全局conto的当前值拷贝一份传入函数,函数内部对形参的加减操作只会修改这份局部拷贝,函数执行结束后局部变量直接销毁,完全不会影响全局的conto值。 - 全局的
conto用const声明,本身就不允许对原始值做重新赋值,就算你去掉形参直接在函数内访问全局conto,const声明的变量也无法修改。 - 你之前尝试的
var conto = conto += test写法不生效,是因为函数内用var声明同名变量会触发变量提升,本质还是在操作函数内部的局部变量,碰不到全局的conto。
修复步骤
- 将全局余额变量的声明从
const conto = 0改为let conto = 0,允许后续重新赋值 - 删除三个函数形参列表中的
conto参数,同时删除根本不需要外部传入的deposito、meno形参——这两个值本来就是在函数内部通过用户输入获取,不需要作为参数传递 - 所有调用
ricarica、prelievo、estrattoConto的位置,去掉传入的conto实参 - 补全for循环中计数器
i的声明,避免隐式创建全局变量
修复后可运行代码
const prompt = require("prompt-sync")(); // 全局余额改用let声明,支持修改 let conto = 0; const ricarica = () => { const deposito = prompt("Quanti soldi vuole depositare sul suo conto? "); conto += Number.parseInt(deposito); console.log(`Ora il suo conto ha una disponibilità residua di ${conto}€`); } const prelievo = () => { const meno = prompt("Quanti soldi vuole prelevare dal suo conto? "); conto -= Number.parseInt(meno); console.log(`Ora il suo conto ha una disponibilità residua di ${conto}€`); } const estrattoConto = () => { console.log(`Ora il suo conto ha una disponibilità residua di ${conto}€`); } const nome = "Tommaso Montanari"; console.log(`\nBuongiorno ${nome} sul suo conto ha una disponibilità di ${conto}€`); let conferma = prompt("Desidera effettuare una ricarica? (Y/N) "); if(conferma === 'Y'){ ricarica(); } else if(conferma === 'N'){ console.log("Arrivederci!"); } else{ console.log("Errore di inserimento"); } do{ const operazioni = [" ", "ricarica", "prelievo", "estratto conto"]; console.log("\nAltre operazioni:"); for(let i = 1; i < 4; i++){ console.log(`${i}. ${operazioni[i]}`); } const quest = prompt("Quale delle seguenti operazioni vuoi eseguire? "); switch(quest){ case '1': ricarica(); break; case '2': prelievo(); break; case '3': estrattoConto(); break; default: console.log("Errore di inserimento"); } const conf = prompt("Vuole eseguire un'altra operazione? (Y/N) "); } while(conf == 'Y')
补充说明
如果后续要做更规范的代码重构,可以避免直接操作全局变量,比如把账户状态封装成对象或者类来管理,不过对于当前这个小型脚本来说,上面的修改已经完全可以实现余额持久存储的需求,多次调用函数修改后的值不会重置。
内容的提问来源于stack exchange,提问作者montax
相关产品推荐
相关产品推荐

