Odin Project石头剪刀布游戏:函数赋值变量传参无效问题求助
问题分析与解决
嘿,这个问题其实是JavaScript里函数引用和函数执行的核心区别,我来给你掰扯清楚~
首先咱们先拆解你遇到的现象:
- 传
computerPlay()正常:因为加括号意味着调用这个函数,你得到的是函数return出来的随机选择字符串(比如'rock'),正好符合playRound对第二个参数的要求。 - 传
computerChoice返回undefined:因为你把computerChoice赋值给了computerPlay函数本身(你写的let computerChoice = function computerPlay() {...}是把函数对象直接赋值给变量),并没有执行它。当你把这个函数对象传给playRound时,computerSelection拿到的是一个函数,不是字符串,你的所有if/else条件都匹配不上,函数自然就返回undefined了。
另外还有个隐藏小坑得提醒你:你原来把rdm定义在全局作用域里,这样不管你调用多少次computerPlay,都会用同一个随机数,电脑每次都选同一个选项!得把随机数的生成放到函数内部,这样每次调用都会重新生成随机数。
修复方案
这里给你两种正确的写法,适配不同场景:
写法1:保留函数引用,调用时加括号(推荐单轮游戏)
把computerPlay赋值给变量后,调用变量时加上括号执行它,拿到返回值再传给playRound:
let choices = ['rock', 'paper', 'scissors']; function playRound(playerSelection, computerSelection) { if (playerSelection === computerSelection) { return 'It is a tie!!!'; } else if (playerSelection === 'rock' && computerSelection === 'paper') { return 'PAPER BEATS ROCK! computer wins!' } else if (playerSelection === 'rock' && computerSelection === 'scissors') { return 'ROCK BEATS SCISSORS! player wins!'; } else if (playerSelection === 'paper' && computerSelection === 'scissors') { return 'SCISSORS BEATS PAPER! computer wins!' } else if (playerSelection === 'paper' && computerSelection === 'rock') { return 'PAPER BEATS ROCK! player wins!'; } else if (playerSelection === 'scissors' && computerSelection === 'rock') { return 'ROCK BEATS SCISSORS! computer wins!' } else if (playerSelection === 'scissors' && computerSelection === 'paper') { return 'SCISSORS BEATS PAPER! player wins!'; } } // 把随机数生成移到函数内部,确保每次调用都重新随机 let computerChoice = function computerPlay() { const rdm = Math.floor(Math.random() * 3); const computer = choices[rdm]; return computer; } // 调用变量时加括号,执行函数拿到返回值 console.log(playRound('rock', computerChoice())); // 现在正常工作!
写法2:直接把函数执行结果赋值给变量(不推荐单轮游戏)
如果你想让computerChoice直接是随机选择的字符串,可以在赋值时就执行函数:
// 赋值时直接执行函数,拿到结果 let computerChoice = (function computerPlay() { const rdm = Math.floor(Math.random() * 3); const computer = choices[rdm]; return computer; })(); console.log(playRound('rock', computerChoice)); // 这时候也能正常运行
不过这种写法的问题是computerChoice的值只会在赋值时生成一次,后续再用它都是同一个选择,不适合需要每次电脑都随机选的单轮游戏场景,所以更推荐第一种写法。
总结一下核心要点:
- 函数名(或赋值了函数的变量)本身是函数引用,代表函数这个对象;
- 函数名加括号
()是执行函数,得到的是函数的返回值; - 随机数逻辑要放在函数内部,才能每次调用都重新生成新的随机选择。
内容的提问来源于stack exchange,提问作者coe
相关产品推荐
相关产品推荐

