javascript中运算符优先级的问题?

测试代码如下:

function fn01() {
    console.log('fn01');
    return false;
}
function fn02() {
    console.log('fn02');
    return true;
}
function fn03() {
    console.log('fn03');
    return true;
}
console.log(fn01() || fn02() && fn03());

运算结果为:

clipboard.png

我感觉这个运算结果很奇怪,因为根据javascript中运算符优先级,&&要比||高,所以应该是先运行fn02,fn02()为true时,再运行fn03,fn03()为true,整个结果就是true了,不需要运算fn01,所以我理解的运算结果应该为:

fn02
fn03
true

下面附上javascript中运算符优先级资料:
运算符优先级

clipboard.png

可以看到“逻辑与&&“比“逻辑或||“要高一级。

clipboard.png

真实的运算结果,和我根据运算符优先级推理出来的结果不一样,是什么原因,错在哪里?

阅读 3.8k
3 个回答
fn01() || fn02() && fn03() === fn01() || (fn02() && fn03())

优先级是结合的优先级,不是表达式求值(执行)的优先级


用后缀表达式看优先级 (参见 JS 实现 JS 引擎 - 二元逻辑运算符的后缀表达式求值)

fn01() || fn02() && fn03()

会变成

fn01() fn02() fn03() && ||

执行时

不断读取后缀表达式,如果遇到操作数,入栈,如果遇到二元操作符,则出栈两个操作数,连同操作符作为一个整体(对象)入栈,等待后续的求值。

待后缀表达式处理完后,栈中应当有且只有一个对象,此时对它进行递归求值即可。


写了一段代码模拟 JS 引擎表达式求值的过程

var vars = {
  var1: false,
  var2: true,
  var3: true,
};
var expr = 'var1 var2 var3 && ||';



class Expr {
  eval() {}
}

class Var extends Expr {
  constructor(v) {
    super();
    this.v = v;
  }
  eval() {
    console.log(this.v);
    return vars[this.v];
  }
}

class BinOp extends Expr {
  constructor(type, a, b) {
    super();
    this.type = type;
    this.a = a;
    this.b = b;
  }
  eval() {
    switch (this.type) {
    case '&&':
      if (this.a.eval()) {
        return this.b.eval();
      }
      return false;
      break;
    case '||':
      var val;
      if (val = this.a.eval()) {
        return val;
      }
      if (val = this.b.eval()) {
        return val;
      }
      return false;
      break;
    }
  }
}

var queue = expr.split(' ');
var stack = [];

while (queue.length) {
  var o = queue.shift();
  switch (o) {
  case '&&':
  case '||':
    var b = stack.pop();
    var a = stack.pop();
    stack.push(new BinOp(o, a, b));
    break;
  default:
    stack.push(new Var(o));
  }
}

console.log(stack[0].eval());

程序输出:

var1
var2
var3
true

为什么我没看到表达式就看到3个函数,不过楼上应该是正解

谢邀,1楼正解,我也没没看到表达式

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题