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

时间:2015-03-14 15:06:27

标签: javascript node.js

请参阅下面的代码:

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有关?

2 个答案:

答案 0 :(得分:4)

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");

答案 1 :(得分:4)

这是因为+运算符被重载以在JavaScript中执行加法和字符串连接。如果任一操作数的类型是字符串,则串联优先。

这描述为in the spec

  

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

     

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

     
      
  1. 让lref成为评估AdditiveExpression的结果。
  2.   
  3. 让lval成为GetValue(lref)。
  4.   
  5. 让rref成为评估MultiplicativeExpression的结果。
  6.   
  7. 让rval为GetValue(rref)。
  8.   
  9. 让lprim为ToPrimitive(lval)。
  10.   
  11. 让rprim为ToPrimitive(rval)。
  12.   
  13. 如果Type(lprim)是String或Type(rprim)是String,那么

         
        
    1. 返回串联ToString(lprim)后跟ToString(rprim)的结果的字符串
    2.   
  14.   
  15. 将添加操作的结果返回到ToNumber(lprim)和ToNumber(rprim)。参见下面的注释11.6.3。
  16.