You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于validBraces函数中if条件语句内stack.pop()执行原理的技术问询

关于validBraces函数中stack.pop()的执行逻辑

首先放上待分析的代码:

function validBraces(braces) { 
  var matches = { '(': ')', '{': '}', '[': ']' }; 
  var stack = []; 
  var currentChar; 
  for (var i = 0; i < braces.length; i++) { 
    currentChar = braces[i]; 
    if (matches[currentChar]) { 
      stack.push(currentChar); 
    } else { 
      if (currentChar !== matches[stack.pop()]) { 
        return false; 
      } 
    } 
  } 
  return stack.length === 0; 
}

你的疑问:

我对这段代码的理解是:currentChar !== matches[stack.pop()] 用于检查当前字符是否与栈(stack)数组最后一个元素对应的闭合括号匹配,若匹配则弹出栈的最后一个元素。但代码中并未编写匹配成功时的条件分支(例如if(currentChar == matches[stack.pop()]) {stack.pop()}这样的结构)。那么,即便没有匹配成功的条件分支,stack.pop()是否仍会在if条件语句中执行?它的具体执行逻辑是怎样的?


这是个非常好的观察点!核心答案是:不管if条件最终成立与否,stack.pop()都会先执行,这是由JavaScript表达式的执行顺序决定的,我来给你拆解清楚:

  1. 表达式的执行顺序
    当代码执行到currentChar !== matches[stack.pop()]时,JavaScript会按照从内到外的顺序计算所有嵌套表达式:

    • 先调用stack.pop(),把栈顶的左括号元素弹出来(这一步会直接修改栈的内容)
    • 再用弹出的这个元素作为key,从matches对象里取出对应的闭合括号
    • 最后把这个取出的闭合括号和currentChar做不等比较
  2. 匹配成功时的逻辑
    如果当前闭合括号和弹出的左括号对应的闭合括号相等(比如currentChar是),弹出的是(,matches['(']就是)),那么currentChar !== matches[stack.pop()]的结果是false,不会进入if块里的return false。这时候栈已经被pop()修改过了——匹配的左括号已经被移除,完全符合我们的需求,不需要额外写分支去重复pop()。

  3. 匹配失败时的逻辑
    如果两者不相等(比如currentChar是],弹出的是(),那么比较结果是true,直接执行return false,终止函数,说明括号不合法。

举个实际的小例子:
假设当前栈是['('],currentChar是):

  • 执行stack.pop(),栈变成空,返回值是'('
  • 取matches['(']得到')'
  • 比较')' !== ')',结果为false,跳过if块,循环继续

另外还要提一句:你之前设想的if(currentChar == matches[stack.pop()]) {stack.pop()}是有问题的——因为这样写的话,stack.pop()会执行两次:一次在条件判断里,一次在if块里,会错误地多弹出一个元素,反而破坏栈的结构。原代码的写法刚好利用了表达式的执行顺序,用一次pop()同时完成了“取出栈顶元素”和“检查匹配”两个操作,非常巧妙。

内容的提问来源于stack exchange,提问作者echo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:37:44