英文:
How can I compare and analyze two scripts for saving/receiving items from local storage?
问题
I'm trying to make sense of the second code but my mind only wraps around the first code which is mine (it's already obvious since it's awful). I understand the ternary operator (and even the second code) but my mind only wants to accept the first code as the better code although it's long and awful (but to me it's more comprehensive); it this a normal behavior at the beginning of my learning? by the way it's been only three days since i started learning JS so feel free to add any advice that might help a stupid like me to improve.
我的代码:
<button onclick="playGame('tails');">tails</button>
<button onclick="playGame('heads');">heads</button>
<script>
let result = '';
let score = {
wins: 0,
losses: 0
}
let scoresFromLocalStorage = localStorage.getItem('scores');
if (scoresFromLocalStorage) {
score = JSON.parse(scoresFromLocalStorage);
}
function playGame(choice) {
const randomNumber = Math.random();
if (randomNumber < 0.5) {
result = 'heads';
} else {
result = 'tails';
}
console.log('Computer: ' + result);
console.log('You: ' + choice);
if (choice === result) {
console.log('You win');
score.wins += 1;
} else {
console.log('You lost');
score.losses += 1;
}
let jsonScore = JSON.stringify(score);
localStorage.setItem('scores', jsonScore);
score = JSON.parse(localStorage.getItem('scores'));
console.log(score);
}
</script>
第二个更好的代码:
<button onclick="playGame('heads');">heads</button>
<button onclick="playGame('tails');">tails</button>
<script>
// 我们可以在这里使用const,因为score是一个引用,
// 所以即使它使用const,我们也可以修改它。
const score = JSON.parse(localStorage.getItem('score')) || {
wins: 0,
losses: 0
};
function playGame(guess) {
const randomNumber = Math.random();
const result = randomNumber < 0.5 ? 'heads' : 'tails';
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
score.wins++;
} else {
score.losses++;
}
console.log(score);
localStorage.setItem('score', JSON.stringify(score));
}
</script>
在两个代码中都成功地将结果保存在localStorage中,但我真的无法理解如何使用第二个代码。
英文:
I'm trying to make sense of the second code but my mind only wraps around the first code which is mine (it's already obvious since it's awful). I understand the ternary operator (and even the second code) but my mind only wants to accept the first code as the better code although it's long and awful (but to me it's more comprehensive); it this a normal behavior at the beginning of my learning?
by the way it's been only three days since i started learning JS so feel free to add any advice that might help a stupid like me to improve.
my code:
<button onclick="
playGame('tails');
">tails</button>
<button onclick="
playGame('heads')
">heads</button>
<script>
let result = '';
let score = {
wins: 0,
losses: 0
}
let scoresFromLocalStorage = localStorage.getItem('scores');
if (scoresFromLocalStorage) {
score = JSON.parse(scoresFromLocalStorage);
}
function playGame(choice) {
const randomNumber = Math.random();
if (randomNumber < 0.5) {
result = 'heads';
} else {
result = 'tails';
}
console.log('Computer: ' + result);
console.log('You: ' + choice);
if (choice === result) {
console.log('You win');
score.wins += 1;
} else {
console.log('You lost');
score.losses += 1;
}
let jsonScore = JSON.stringify(score);
localStorage.setItem('scores', jsonScore);
score = JSON.parse(localStorage.getItem('scores'));
console.log(score);
}
</script>
second or the better code:
<button onclick="
playGame('heads');
">heads</button>
<button onclick="
playGame('tails');
">tails</button>
<script>
// We can use const here since score is a reference
// so we can modify it even if it uses const.
const score = JSON.parse(localStorage.getItem('score')) || {
wins: 0,
losses: 0
};
function playGame(guess) {
const randomNumber = Math.random();
const result = randomNumber < 0.5 ? 'heads' : 'tails';
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
score.wins++;
} else {
score.losses++;
}
console.log(score);
localStorage.setItem('score', JSON.stringify(score));
}
</script>
Saving the results in localStorage, which in both codes is a success. but i really can't wrap my head around using the second code.
答案1
得分: 0
In my case, I used to use long code instead of short efficient code.
但随着时间的推移,我想要缩短我的代码。所以我改变了我的代码风格,像第二个一样。我认为你的行为(更喜欢长代码)是初学者程序员中的通用行为(甚至是专业程序员)。
顺便说一下。我想建议你一些改进。
'++' 和 '--' 运算符这些天用得不太好。
你可以像你之前做的那样使用 '+=' 运算符(score.wins += 1
)。
这是我的主观建议。
在第二个代码中,<br>
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
score.wins++;
} else {
score.losses++;
}
<br>
你的代码比这个代码更好。
因为你的代码比第二个代码更直观。
我更喜欢按照它们的角色分类来分离代码。
你不需要采纳我的建议,因为我不是专业程序员,甚至我英语也不太好... 抱歉我的语法错误和上下文错误。
英文:
In my case, I used to use long code instead of short effcient code.
But as time goes by, I wanted to make my code shorter. So I changed my code style like second one. I think your behavior(prefer long codes) is general behaviors among beginer of programers. (Even professional programers)
By the way. I'd like to suggest you some improvement.
'++' and '--' operators are not used very well these days.
You can use '+=' operators as you did. (score.wins += 1
).
And this is my subjective suggestion.
In second code, <br>
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
score.wins++;
} else {
score.losses++;
}
<br>
your code is better than this code.
because your code is more intuitive than second code.
I prefer seperate codes by same categories of their roles.
You don't need to apply my suggestion because I'm not a professional programer and even I'm not good at English.... Sry for my grammar errors and a contextual flaw.
答案2
得分: 0
以下是您要翻译的内容:
"I'm not sure what you mean by "how can I compare and analyze two scripts", but I will do it myself below and you can follow along.
As to "normal behavior", I'm sure it's pretty common to feel like this.
(I feel the core question is rather opinion based, but the individual concepts are useful.)
Comparison
As is, I prefer the other code.
It's quite hard to compare code side-by-side in Markdown, especially as the structure is different, so I'll try go through the logical sections. Here goes...
I've used only the script, as the HTML is the same.
I've normalized the 'scores' and 'score' names and keys to 'scores'.
Getting the scores from storage or using a default
Your code:
let scores = {
wins: 0,
losses: 0
}
let scoresFromLocalStorage = localStorage.getItem('scores');
if (scoresFromLocalStorage) {
scores = JSON.parse(scoresFromLocalStorage);
}
Other code:
const scores = JSON.parse(localStorage.getItem('scores')) || {
wins: 0,
losses: 0
};
Your code creates a mutable variable set to the default value. It then reads the data from localStorage and stores it in a variable. If the variable is not falsy (i.e., the item exists in storage and is not an empty string), the value is parsed as JSON and assigned to the 'scores' variable.
The other code reads the data from localStorage and parses it. Assuming the data is valid if present, this will either return a scores object or null. It then uses a logical or (||) to choose between this and the default: if it is falsy, the default is used. (I would use ??, the nullish coalescing operator ??; it's designed specifically for this kind of use case.)
Ignoring the differences in behavior when the stored data is not what is expected, these two pieces of code are identical in outcome, aside from the difference between let and const.
Here's an intermediate refactoring of your code:
let scoresFromLocalStorage = JSON.parse(localStorage.getItem('scores'));
const scores = scoresFromLocalStorage
? scoresFromLocalStorage
: {
wins: 0,
losses: 0
};
The next step is replacing the temp variable and ternary with a logical or operator or nullish coalescing operator, as in the other code.
'playGame' function
I have renamed your 'choice' variable to 'guess' for ease of comparison.
Your code has this extra bit that the other code does not:
console.log('Computer: ' + result);
console.log('You: ' + guess);
I have left it out for the comparisons.
Getting a random number
You both do:
const randomNumber = Math.random();
Determining the result
Your code:
// Top-level
let result = '';
// In function
if (randomNumber < 0.5) {
result = 'heads';
} else {
result = 'tails';
}
Other code:
const result = randomNumber < 0.5 ? 'heads' : 'tails';
The main difference here is that you use an if and the other code uses a ternary. as a consequence, your code needs the variable declared earlier, so that it can be reassigned.
For some reason, you use a global variable instead of a function-local variable; you can instead declare the variable inside the function instead of at the top level scope.
Determining if the guess was correct
I have changed the other code's ++ to += 1 for the sake of comparison.
And the log messages.
Your code:
if (guess === result) {
console.log('You win!');
scores.wins += 1;
} else {
console.log('You lose!');
scores.losses += 1;
}
The other code:
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
scores.wins += 1;
} else {
scores.losses += 1;
}
The only difference here is that the other code opts to do the comparison twice to allow the use of a single log statement, instead of doing the comparison once and having the extra line.
In real code, the choice should be made based on the context.
Alternative code:
console.log(guess === result ? 'You win!' : 'You lose!');
scores[guess === result ? 'wins' : 'losses'] += 1;
Don't use this for this simple case. In more complex situations, though, variations of this actually can be really useful, especially when there are lots of abstractions. E.g., when using a map to determine the key, instead of an equality check.
Logging and storing the result
Your code:
let jsonScores = JSON.stringify(scores); // Stringify
localStorage.setItem('scores', jsonScores); // Store
scores = JSON.parse(localStorage.getItem('scores')); // Load, parse and assign
console.log(scores); // Log
Other code:
console.log(scores); // Log
localStorage.setItem('scores', JSON.stringify(scores)); // Stringify and store
Okay, you lost me here. You stringify the scores object, store it, load it from storage, parse it, and assign it to the scores variable. Why? The storing does not affect the scores object. The only difference this would ever make would be if there were values in the object that could not be stringified, in which case this is not the way to go about and your code is broken. There is no need for this pointless cycle; removing the "load, parse, assign" bit and refactoring to remove the temporary variable gives you the other code:
Remove:
let jsonScores = JSON.stringify(scores); // Stringify
localStorage.setItem('scores', jsonScores); // Store
console.log(scores); // Log
Refactor (optional):
localStorage.setItem('scores', JSON.stringify(scores)); // Stringify and store
console.log(scores); // Log
Reorder the statements if wanted/needed.
Notes
The other code uses approaches that reduce the use of temporary variables. This is very useful in TypeScript, especially in the case of ones that would have to either have an arbitrary default that is never used, or have 'undefined' included in the type (which is a pain). For example, the two methods of determining the result based on the random number."
请注意,上述内容已经翻译成中文。如果您需要任何其他翻译,请告诉我。
英文:
I'm not sure what you mean by "how can I compare and analyze two scripts", but I will do it myself below and you can follow along.
As to "normal behavior", I'm sure it's pretty common to feel like this.
(I feel the core question is rather opinion based, but the individual concepts are useful.)
Comparison
As is, I prefer the other code.
It's quite hard to compare code side-by-side in Markdown, especially as the structure is different, so I'll try go through the logical sections. Here goes...
I've used only the script, as the HTML is the same.
I've normalized the 'scores'
and 'score'
names and keys to 'scores'
.
Getting the scores from storage or using a default
Your code:
let scores = {
wins: 0,
losses: 0
}
let scoresFromLocalStorage = localStorage.getItem('scores');
if (scoresFromLocalStorage) {
scores = JSON.parse(scoresFromLocalStorage);
}
Other code:
const scores = JSON.parse(localStorage.getItem('scores')) || {
wins: 0,
losses: 0
};
Your code creates a mutable variable set to the default value. It then reads the data from localStorage and stores it in a variable. If the variable is not falsy (i.e., the item exists in storage and is not an empty string), the value is parsed as JSON and assigned to the scores
variable.
The other code reads the data from localStorage and parses it. Assuming the data is valid if present, this will either return a scores object or null
. It then uses a logical or (||
) to choose between this and the default: if it is falsy, the default is used. (I would use ??
, the nullish coalescing operator ??
; it's designed specifically for this kind of use case.)
Ignoring the differences in behavior when the stored data is not what is expected, these two pieces of code are identical in outcome, aside from the difference between let
and const
.
Here's an intermediate refactoring of your code:
let scoresFromLocalStorage = JSON.parse(localStorage.getItem('scores'));
const scores = scoresFromLocalStorage
? scoresFromLocalStorage
: {
wins: 0,
losses: 0
};
The next step is replacing the temp variable and ternary with a logical or operator or nullish coalescing operator, as in the other code.
playGame
function
I have renamed your choice
variable to guess
for ease of comparison.
Your code has this extra bit that the other code does not:
console.log('Computer: ' + result);
console.log('You: ' + guess);
I have left it out for the comparisons.
Getting a random number
You both do:
const randomNumber = Math.random();
Determining the result
Your code:
// Top-level
let result = '';
// In function
if (randomNumber < 0.5) {
result = 'heads';
} else {
result = 'tails';
}
Other code:
const result = randomNumber < 0.5 ? 'heads' : 'tails';
The main difference here is that you use an if
and the other code uses a ternary. as a consequence, your code needs the variable declared earlier, so that it can be reassigned.
For some reason, you use a global variable instead of a function-local variable; you can instead declare the variable inside the function instead of at the top level scope.
Determining if the guess was correct
I have changed the other code's ++
to += 1
for the sake of comparison.
And the log messages.
Your code:
if (guess === result) {
console.log('You win!');
scores.wins += 1;
} else {
console.log('You lose!');
scores.losses += 1;
}
The other code:
console.log(guess === result ? 'You win!' : 'You lose!');
if (guess === result) {
scores.wins += 1;
} else {
scores.losses += 1;
}
The only difference here is that the other code opts to do the comparison twice to allow the use of a single log statement, instead of doing the comparison once and having the extra line.
In real code, the choice should be made based on the context.
Alternative code:
console.log(guess === result ? 'You win!' : 'You lose!');
scores[guess === result ? 'wins' : 'losses'] += 1;
Don't use this for this simple case. In more complex situations, though, variations of this actually can be really useful, especially when there are lots of abstractions. E.g., when using a map to determine the key, instead of an equality check.
Logging and storing the result
Your code:
let jsonScores = JSON.stringify(scores); // Stringify
localStorage.setItem('scores', jsonScores); // Store
scores = JSON.parse(localStorage.getItem('scores')); // Load, parse and assign
console.log(scores); // Log
Other code:
console.log(scores); // Log
localStorage.setItem('scores', JSON.stringify(scores)); // Stringify and store
Okay, you lost me here. You stringify the scores object, store it, load it from storage, parse it, and assign it to the scores variable. Why? The storing does not affect the scores object. The only difference this would ever make would be if there were values in the object that could not be stringified, in which case this is not the way to go about and your code is broken. There is no need for this pointless cycle; removing the "load, parse, assign" bit and refactoring to remove the temporary variable gives you the other code:
Remove:
let jsonScores = JSON.stringify(scores); // Stringify
localStorage.setItem('scores', jsonScores); // Store
console.log(scores); // Log
Refactor (optional):
localStorage.setItem('scores', JSON.stringify(scores)); // Stringify and store
console.log(scores); // Log
Reorder the statements if wanted/needed.
Notes
The other code uses approaches that reduce the use of temporary variables. This is very useful in TypeScript, especially in the case of ones that would have to either have an arbitrary default that is never used, or have undefined
included in the type (which is a pain). For example, the two methods of determining the result based on the random number.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论