两段JavaScript代码输出一致的原因及userMsg赋值逻辑解析
两段JavaScript代码输出一致的原因及变量取值逻辑
核心结论
在第一段代码的toUser函数执行时,userMsg的值是最初赋值的message参数,而非toUser("Bob")的返回值。两段代码输出一致,本质是因为它们的执行逻辑完全等价。
拆解第一段代码的执行流程
function giveMessage(message) { let userMsg = message; userMsg = toUser("Bob"); return userMsg; function toUser(userName) { let name = userName; let greet = userMsg + name; return greet; } } console.log(giveMessage("The world says hello dear: ")); // 输出: The world says hello dear: Bob
执行步骤:
- 调用
giveMessage时,参数message被赋值为"The world says hello dear: "。 - 执行
let userMsg = message;,此时userMsg的值就是传入的字符串。 - 执行
userMsg = toUser("Bob");:- 先调用
toUser("Bob"),此时userMsg还没被重新赋值(因为toUser还没执行完返回结果)。 - 进入
toUser函数,greet = userMsg + name中的userMsg取的是作用域链上当前的userMsg值——也就是步骤2里的初始字符串,加上name("Bob")后返回拼接结果。 - 把
toUser的返回值赋值给userMsg,最后return userMsg输出结果。
- 先调用
第二段代码的等价性
function giveMessage(message) { let userMsg = message; let hello = toUser("Bob"); return hello; function toUser(userName) { let name = userName; let greet = userMsg + name; return greet; } } console.log(giveMessage("The world says hello dear: ")); // 输出: The world says hello dear: Bob
这段代码只是把接收toUser返回值的变量从userMsg换成了hello,但调用toUser时的逻辑完全没变:
userMsg依然是初始的message值,toUser返回的还是初始字符串+"Bob"。- 最后返回的
hello和第一段返回的userMsg是同一个值,所以输出完全一致。
关键逻辑点
- JavaScript中,函数声明会被提升,所以
toUser函数可以在定义之前被调用。 - 赋值语句
userMsg = toUser("Bob")是先执行右侧的函数调用,拿到返回值后再给userMsg赋值。这意味着在toUser内部执行时,userMsg还是赋值前的初始值。
内容的提问来源于stack exchange,提问作者zachary colten
相关产品推荐
相关产品推荐

