JavaScript封装可复用函数后变量状态不更新,独立逻辑正常是什么原因?
问题根本原因
你遇到的问题是JavaScript的值传递规则导致的:
- 字符串属于JS的原始值类型(基础类型),当你把
moto1作为参数传入checkMotoGarage函数时,实际传递的是moto1的值副本,不是原变量本身的引用 - 你在函数内部对参数
motonumber的所有修改,都只会改动这个临时副本,完全不会影响到外部的全局变量moto1,所以状态看起来就像没有更新一样。
修复方案
你可以用以下两种常用方案解决:
方案1:让封装函数返回修改后的状态值,外部接收赋值
改造后代码如下:
let moto1=''; function checkMoto1() { // 接收函数返回的新状态,赋值给全局moto1 moto1 = checkMotoGarage(moto1, btn1); }; function checkMotoGarage(motonumber, btnnumber) { if (myMotosInTheGarage === 0 && motonumber === '') { openAlert(displaySorryAlert); } else if (myMotosInTheGarage === 0 && motonumber === 'out') { motonumber = 'return'; myMotosInTheGarage++; countMotos; changeBackground(btnnumber, 'red'); console.log(`the ${btnnumber} it's ${motonumber}`); } else if (myMotosInTheGarage >= 0) { if (motonumber === '') { motonumber = 'out'; myMotosInTheGarage--; countMotos; changeBackground(btnnumber, 'green'); console.log(`the ${btnnumber} it's ${motonumber}`); } else if (motonumber === 'out') { motonumber = 'return'; myMotosInTheGarage++; countMotos; changeBackground(btnnumber, 'red'); console.log(`the ${btnnumber} it's ${motonumber}`); } } // 新增:返回修改后的状态值 return motonumber; };
方案2:把所有摩托状态存在一个对象里,利用对象按引用传递的特性修改
对象属于引用类型,传参时传递的是内存地址引用,函数内部修改会直接作用到原对象,后续新增多台摩托时扩展也更方便:
// 把摩托状态统一存在对象里 const motoStatus = { moto1: '' } function checkMoto1() { // 传入状态对象的key,不用传值本身 checkMotoGarage('moto1', btn1); }; function checkMotoGarage(motoKey, btnnumber) { // 直接操作原对象的属性 const motonumber = motoStatus[motoKey]; if (myMotosInTheGarage === 0 && motonumber === '') { openAlert(displaySorryAlert); } else if (myMotosInTheGarage === 0 && motonumber === 'out') { motoStatus[motoKey] = 'return'; myMotosInTheGarage++; countMotos; changeBackground(btnnumber, 'red'); console.log(`the ${btnnumber} it's ${motoStatus[motoKey]}`); } else if (myMotosInTheGarage >= 0) { if (motonumber === '') { motoStatus[motoKey] = 'out'; myMotosInTheGarage--; countMotos; changeBackground(btnnumber, 'green'); console.log(`the ${btnnumber} it's ${motoStatus[motoKey]}`); } else if (motonumber === 'out') { motoStatus[motoKey] = 'return'; myMotosInTheGarage++; countMotos; changeBackground(btnnumber, 'red'); console.log(`the ${btnnumber} it's ${motoStatus[motoKey]}`); } } };
额外提示
你最初的基础代码里有个语法笔误,changeBackground(btn1, 'red'缺少右闭合括号,实际运行时会触发语法报错。
内容的提问来源于stack exchange,提问作者John McKrazy
相关产品推荐
相关产品推荐

