带内嵌函数的函数表达式参数传递机制及调用疑问
理解嵌套函数的参数传递与闭包
为什么tryGuess的参数传给了内部的guess函数?
首先把你的代码修正为标准JavaScript函数声明格式:
function makePassword(password) { return function guess(passwordGuess) { return passwordGuess === password; }; } var tryGuess = makePassword("secret"); console.log("Guessing 'nope': " + tryGuess("nope")); // false console.log("Guessing 'secret': " + tryGuess("secret")); // true
这里的核心逻辑是闭包和函数执行时机:
- 调用
makePassword("secret")时,makePassword会立即执行:它接收参数password = "secret",然后返回内部定义的guess函数引用。 - 此时
makePassword已经执行完毕,但guess函数通过闭包保留了对makePassword作用域中password变量的访问权——也就是说,guess记住了password的值是"secret"。 - 变量
tryGuess存储的是guess函数的引用,所以调用tryGuess("nope")本质上是调用guess("nope"),参数自然传给guess,而非已经执行完成的makePassword。
如果var tryGuess = makePassword(),怎么传递password和passwordGuess?
当调用makePassword()不传参时,makePassword里的password会是undefined。可以调整逻辑,让返回的函数支持先设置密码、再进行猜测的流程,利用闭包保存后续设置的密码:
方案1:分两步设置密码与猜测
function makePassword(initialPassword) { let storedPassword = initialPassword; return function(input) { if (storedPassword === undefined) { // 未设置密码时,将输入作为密码存储 storedPassword = input; // 返回专门用于猜测的函数 return function(passwordGuess) { return passwordGuess === storedPassword; }; } else { // 已设置密码,直接判断猜测是否正确 return input === storedPassword; } }; } // 用法:先设置密码,再猜 var tryGuess = makePassword(); var guessFunction = tryGuess("secret"); console.log(guessFunction("nope")); // false console.log(guessFunction("secret")); // true // 也支持初始直接传密码,直接猜测 var tryGuess2 = makePassword("secret"); console.log(tryGuess2("nope")); // false
方案2:支持双参数一次完成设置与猜测
如果你希望一次调用完成密码设置和猜测,也可以让返回的函数支持两种传参模式:
function makePassword() { let storedPassword; return function(pwd, guess) { if (guess === undefined) { // 仅传一个参数时,作为密码存储 storedPassword = pwd; return; } else { // 传两个参数时,先设置密码再判断猜测 storedPassword = pwd; return guess === storedPassword; } }; } var tryGuess = makePassword(); tryGuess("secret"); // 设置密码 console.log(tryGuess("secret", "nope")); // false console.log(tryGuess("secret", "secret")); // true
关键知识点总结
- 函数执行时机:当你写
var fn = outer()时,outer会立即执行,返回的是内部函数的引用,后续调用fn()都是在调用内部函数。 - 闭包:嵌套的内部函数会保留对外部函数作用域的访问权,即使外部函数执行完毕,内部函数依然能访问外部函数的变量。
- 参数传递:函数的参数仅在调用该函数时生效,已经执行完成的函数不会再接收新参数。
内容的提问来源于stack exchange,提问作者Russ Urquhart
相关产品推荐
相关产品推荐

