JavaScript:通过console.log输出意外('str'+ int + int)

请参阅下面的代码:

var fs = require('fs'); var file = 'test.js'; var search = new RegExp("\n", "g"); function printLineNum(err, fileContents) { if (err) return console.error(err.message); console.log("Total line(s) of document: %d", fileContents.match(search).length + 1); } fs.readFile(file, 'utf8', printLineNum); // output: Total line(s) of document: 10 

这是一段代码。 但在我做出改变之前,第7行看起来像:

 console.log("Total line(s) of document: " + fileContents.match(search).length + 1); // output: 91 

意外的错误也可以通过在数字中加上括号来解决:

 console.log("Total line(s) of document: " + (fileContents.match(search).length + 1)); // output: 10 

我知道如何避免这个错误,但我无法弄清楚什么是错的。 这是一个JavaScript的事情或与console.log

 console.log("Total line(s) of document: " + fileContents.match(search).length + 1); 

在这种情况下,连接运算符优先于加法运算符,并首先进行评估。

该声明将被评估如下:

 // string concatenation happens first console.log((("string" + 9) + 1)); // resulting in more string concatenation console.log(("string9" + 1)); console.log("string91"); 

这是由于+运算符被重载以在JavaScript中执行加法和string连接的事实。 如果任一操作数的types是一个string,则连接优先。

这在spec中描述:

加法运算符可以执行string连接或数字加法。

生产AdditiveExpression:AdditiveExpression + MultiplicativeExpression的计算方法如下:

  1. 让lref是评估AdditiveExpression的结果。
  2. 让lval成为GetValue(lref)。
  3. 让rref是评估MultiplicativeExpression的结果。
  4. 让rval是GetValue(rref)。
  5. 让lprim成为原文(lval)。
  6. 让rprim成为原始(rval)。
  7. 如果Type(lprim)是String或Type(rprim)是String,那么

    1. 返回连接ToString(lprim)后跟ToString(rprim)的string,
  8. 将加法操作的结果返回给ToNumber(lprim)和ToNumber(rprim)。 见下面的注释11.6.3。