好吧,所以我有几个函数,其中两个(在底部)保存和加载所有变量到本地存储。其中两个(在底部)保存和加载所有变量到本地存储和从本地存储。我还有一些函数可以添加到这些变量中。在我保存和加载之前,它们都能正常工作。当我保存和加载时,不是从1到2,而是从1到11,再到111,以此类推。为什么会发生这种情况,我该如何解决?
EDIT:我很确定我需要将一个字符串从localstorage转换为一个数字,并将这个数字分配给一个特定的变量。
var moneyAdd = 1;
var money = 1000
var crystals = 0
var wood = 0;
var metal = 0;
var sword = 0;
var rsword = 0;
var hasAnvil = false;
function resetVars() {
moneyAdd = 1;
money = 1000
crystals = 0
wood = 0;
metal = 0;
sword = 0;
rsword = 0;
hasAnvil = false;
}
function getCrystal() {
crystal += 1
}
function getMetal() {
metal += 1
}
function getWood() {
wood += 1
}
function displayInventory() {
alert("Here is your inventory:\n" + money + " Money\n" + crystals + " Crystals\n" + wood + " Wood\n" + metal + " Metal\n" + sword + " Sword(s)\nHas Anvil (" + hasAnvil + ")\n" + rsword + " Reinforced Swords\n")
}
function addMoney() {
money += moneyAdd;
}
function displayMoney() {
alert("You have " + money + " moneys!");
}
function displayCrystals() {
alert("You have " + crystals + " crystals!");
}
function displayWood() {
alert("You have " + wood + " wood!");
}
function displayMetal() {
alert("You have " + metal + " metal!");
}
function craftSword() {
var r = confirm("Are you sure you want to buy one basic sword for 2 metal, 1 wood, and 1 crystal?");
if (r == true) {
if (crystals >= 1 && wood >= 1 && metal >= 2) {
wood -= 1;
crystals -= 1;
metal -= 2;
sword += 1;
alert("Transaction completed. You now have " + sword + " basic swords.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function craftRSword() {
var r = confirm("Are you sure you want to craft one reinforced sword with 1 basic sword and 2 metal with an anvil?");
if (r == true) {
if (sword >= 1 && metal >= 2 && hasAnvil == true) {
sword -=1;
metal -= 2;
rsword += 1;
alert("Transaction completed. You now have " + rsword + " reinforced swords.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function craftAnvil() {
var r = confirm("Are you sure you want to craft one iron anvil for 4 metal?");
if (r == true) {
if (metal >= 4) {
metal -= 4;
hasAnvil = true;
alert("Transaction completed. You now have an anvil (" + hasAnvil + ").")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function sellSword() {
var r = confirm("Are you sure you want to sell a basic sword and grab 150 money?");
if (r == true) {
if (sword >= 1) {
money += 150;
sword -= 1;
alert("Transaction completed. You now have sold a basic sword and now have " + money + " moneys.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function sellRSword() {
var r = confirm("Are you sure you want to sell a reinforced sword and grab 250 money?");
if (r == true) {
if (rsword >= 1) {
money += 250;
rsword -= 1;
alert("Transaction completed. You now have sold a reinforced sword and now have " + money + " moneys.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function buyCrystal() {
var r = confirm("Are you sure you want to buy a Crystal for 100 Moneys?");
if (r == true) {
if (money >= 100) {
money -= 100;
crystals += 1;
alert("Transaction completed. You now have " + crystals + " crystals.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function buyWood() {
var r = confirm("Are you sure you want to buy one wood for 20 Moneys?");
if (r == true) {
if (money >= 20) {
money -= 20;
wood += 1;
alert("Transaction completed. You now have " + wood + " wood.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function buyMetal() {
var r = confirm("Are you sure you want to buy one metal for 40 Moneys?");
if (r == true) {
if (money >= 40) {
money -= 40;
metal += 1;
alert("Transaction completed. You now have " + metal + " metal.")
} else {
alert("Insufficient Funds. Transaction Cancelled.");
}
} else {
alert("Transaction cancelled.");
}
}
function saveVars() {
localStorage.setItem('moneyAdd', moneyAdd);
localStorage.setItem('money', money);
localStorage.setItem('crystals', crystals);
localStorage.setItem('wood', rsword);
localStorage.setItem('metal', metal);
localStorage.setItem('sword', sword);
localStorage.setItem('rsword', rsword);
localStorage.setItem('hasAnvil', hasAnvil);
}
function loadVars() {
moneyAdd = localStorage.getItem('moneyAdd');
money = localStorage.getItem('money');
crystals = localStorage.getItem('crystals');
wood = localStorage.getItem('wood');
metal = localStorage.getItem('metal');
sword = localStorage.getItem('sword');
rsword = localStorage.getItem('rsword');
hasAnvil = localStorage.getItem('hasAnvil');
}
我如何解决这个问题,为什么会发生这种情况?
你处理的是字符串,localStorage总是返回一个字符串,所以'1'+1将是11。你需要将字符串转换为数字、布尔值等。
也许在 loadVars()
像。
function loadVars() {
moneyAdd = +localStorage.getItem('moneyAdd');
money = +localStorage.getItem('money');
crystals = +localStorage.getItem('crystals');
wood = +localStorage.getItem('wood');
metal = +localStorage.getItem('metal');
sword = +localStorage.getItem('sword');
rsword = +localStorage.getItem('rsword');
hasAnvil = localStorage.getItem('hasAnvil') === 'true'
}
你保存到localStorage的所有内容都会变成一个字符串值。
LocalStorage是一个键值存储,用于存储 <string, string>
情侣。
所以你必须在加载时将字符串值转换为数字。
试试像(对所有变量)这样的东西。
moneyAdd = +localStorage.getItem('moneyAdd');
怎么样利用 JSON.stringify
在存储数据之前,以及 JSON.parse
从仓库拿回来后。它 "蜜饯" 的类型。我们不需要单独处理一个数据的正确类型转换过程。我还建议对一个游戏的所有玩家数据使用一个确切的存储对象。
设置一个数据对象的存储键可以是游戏名称和玩家个人用户名的组合......比如......。
localStorage.setItem('adventure-x-charlie', JSON.stringify(data));
......与 data
看起来像那样......。
const data = { moneyAdd: 1, money: 1000, crystals: 0, wood: 0, metal: 0, sword: 0, rsword: 0, hasAnvil: false };
OP的重构后的示例代码可能会证明刚才所说的内容(不幸的是 localStorage
对沙盒的 "SO代码盒 "不起作用,但是...)。) 将下面的代码粘贴到 developer-tools 控制台中也能起到作用......
const RolePlay = (function () {
// local module functionality
// ... dealing with session data
const defaultSessionData = {
// profitValue: 1
moneyAdd: 1,
money: 1000,
crystal: 0,
wood: 0,
metal: 0,
sword: 0,
rsword: 0,
hasAnvil: false
};
function resetSessionData(data) {
return Object.assign(data, defaultSessionData);
}
function getInitialSessionData(sessionId) {
return (
JSON.parse(localStorage.getItem(sessionId))
|| resetSessionData({})
);
}
function persistSessionData(sessionId, data) {
return localStorage.setItem(sessionId, JSON.stringify(data));
}
// local module functionality
// ... dealing with session data display
function displayCrystalCount(data) {
alert(`You own ${ data.crystal } crystal(s).`);
}
function displayMetalCount(data) {
alert(`You have ${ data.metal } metal(s).`);
}
function displayWoodCount(data) {
alert(`You have ${ data.wood } wood(s).`);
}
function displaySavings(data) {
alert(`You 've got ${ data.money } bucks.`);
}
function displayInventory(data) {
alert(`\
Here is your inventory:\n\
${ data.money } bucks\n\
${ data.crystal } crystal(s)\n\
${ data.wood } wood(s)\n\
${ data.metal } metal(s)\n\
${ data.sword } sword(s)\n\
has anvil (${ data.hasAnvil })\n\
${ data.rsword } reinforced sword(s)\
`);
}
// local module functionality
// ... dealing with state changes of session data
function incrementInventoryCount(data, key, value) {
data[key] = (data[key] + (value || 1));
}
function decrementInventoryCount(data, key, value) {
data[key] = (data[key] - (value || 1));
}
function craftBasicSword(data) {
const isConfirmed = confirm(`\
Are you sure you want to buy one basic sword\
for 2 metals, 1 wood, and 1 crystal?\
`);
if (isConfirmed) {
if (
data.crystal >= 1
&& data.wood >= 1
&& data.metal >= 2
) {
decrementInventoryCount(data, 'metal', 2);
decrementInventoryCount(data, 'wood');
decrementInventoryCount(data, 'crystal');
incrementInventoryCount(data, 'sword');
alert(`\
Transaction completed. You now have\
${ data.sword } basic sword(s).\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
function craftReinforcedSword(data) {
const isConfirmed = confirm(`\
Are you sure you want to craft one reinforced sword\
with 1 basic sword and 2 metals with an anvil?\
`);
if (isConfirmed) {
if (
data.hasAnvil
&& data.sword >= 1
&& data.metal >= 2
) {
decrementInventoryCount(data, 'sword');
decrementInventoryCount(data, 'metal', 2);
incrementInventoryCount(data, 'rsword');
alert(`\
Transaction completed. You now have\
${ data.rsword } reinforced sword(s).\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
function craftAnvil(data) {
const isConfirmed = confirm(`\
Are you sure you want to craft\
one iron anvil for 4 metals?\
`);
if (isConfirmed) {
if (data.metal >= 4) {
decrementInventoryCount(data, 'metal', 4);
data.hasAnvil = true;
alert(`\
Transaction completed. You now have\
an anvil (${ data.hasAnvil }).\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
function sellBasicSword(data) {
const isConfirmed = confirm(`\
Are you sure you want to sell\
a basic sword and grab 150 bucks?\
`);
if (isConfirmed) {
if (data.sword >= 1) {
incrementInventoryCount(data, 'money', 150);
decrementInventoryCount(data, 'sword');
alert(`\
Transaction completed. You've just sold a basic sword.\
You now have ${ data.sword } basic sword(s)\
and ${ data.money } bucks in total.\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
function sellReinforcedSword(data) {
const isConfirmed = confirm(`\
Are you sure you want to sell\
a reinforced sword and grab 250 bucks?\
`);
if (isConfirmed) {
if (data.rsword >= 1) {
incrementInventoryCount(data, 'money', 250);
decrementInventoryCount(data, 'rsword');
alert(`\
Transaction completed. You've just sold a reinforced sword.\
You now have ${ data.sword } reinforced sword(s)\
and ${ data.money } bucks in total.\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
function buyOneBasicInventory(data, key, value) {
const isConfirmed = confirm(`\
Are you sure you want to buy one\
${ key } for ${ value } bucks?\
`);
if (isConfirmed) {
if (data.money >= value) {
decrementInventoryCount(data, 'money', value);
incrementInventoryCount(data, key);
alert(`\
Transaction completed.\
You now have ${ data[key] } ${ key }(s).\
`);
} else {
alert('Insufficient Funds. Transaction Cancelled.');
}
} else {
alert('Transaction cancelled.');
}
}
// Session constructor
function Session(sessionId, options/* { moneyAdd: 10 } */) {
// locally scoped session state for each session instance.
const state = Object.assign(
// get initial state either from local storage or from default configuration.
getInitialSessionData(sessionId),
// be capable of overwriting some of the session data via an `options` object.
(options || {})
);
// debugger;
this.persistData = function () {
// debugger;
persistSessionData(sessionId, state);
};
// could be `gainMoney`
this.addMoney = function () {
incrementInventoryCount(state, 'money', state.moneyAdd);
// incrementInventoryCount(state, 'money', state.profitValue);
};
// should be `addCrystal`
this.getCrystal = function () {
incrementInventoryCount(state, 'crystal');
};
// should be `addMetal`
this.getMetal = function () {
incrementInventoryCount(state, 'metal');
};
// should be `addWood`
this.getWood = function () {
incrementInventoryCount(state, 'wood');
};
this.buyCrystal = function () {
buyOneBasicInventory(state, 'crystal', 100);
};
this.buyMetal = function () {
buyOneBasicInventory(state, 'metal', 40);
};
this.buyWood = function () {
buyOneBasicInventory(state, 'wood', 20);
};
this.displayCrystals = function () {
displayCrystalCount(state);
};
this.displayMetal = function () {
displayMetalCount(state);
};
this.displayWood = function () {
displayWoodCount(state);
};
this.displayMoney = function () {
displaySavings(state);
};
this.displayInventory = function () {
displayInventory(state);
};
this.craftAnvil = function () {
craftAnvil(state);
};
this.craftSword = function () {
craftBasicSword(state);
};
this.craftRSword = function () {
craftReinforcedSword(state);
};
this.sellSword = function () {
sellBasicSword(state);
};
this.sellRSword = function () {
sellReinforcedSword(state);
};
}
// `RolePlay` module with `Session` constructor
return {
Session: Session
};
}());
const session = new RolePlay.Session('RolePlayX_charlie', { moneyAdd: 10 });
console.log('Object.keys(session) : ', Object.keys(session));
session.persistData();
console.log('recoveredSessionData : ', JSON.parse(localStorage.getItem('RolePlayX_charlie')));