当从JavaScript运行MongoDB命令时,评论代码被执行

Mongo.exe尝试在我的JavaScript文件中执行注释行?

我在JavaScript文件中有一组MongoDB Shell命令。

use test; /* var categories = []; var sum = 0; var category = { _id: "", num: 0 }; var cur = db.itemdata.aggregate( [ { $group: { _id: "$category" , num : {$sum: 1 } }}, { $sort: {"_id":1 }} ]).toArray(); for(var i=0; i < cur.length; i++){ sum += cur[i].num; categories.push(cur[i]); } category.num = sum; categories.unshift(category); */ /* Example 2 */ var category = 'Books'; var cnt = db.itemdata.find({"category" : category}).count() print(cnt); 

我得到了Exampe2下代码的预期结果。 但是,我在terminal中看到一些警告/信息。

2016-07-06T11:44:35.886-0500 E QUERY [thread1] SyntaxError:unterminated comment @(shell):3:0
2016-07-06T11:44:35.889-0500 E QUERY [thread1] ReferenceError:类别未定义:@(shell):3:2
2016-07-06T11:44:35.891-0500 E QUERY [thread1] ReferenceError:类别未定义:@(shell):1:1
3
再见

我使用以下命令/语法在Windows机器上执行JavaScript文件:

 mongo.exe < script.js 

为什么我会看到这些错误,即使categoriesvariables位于注释块内部。

这不是一个showstopper,想了解为什么发生?

这可能是由于mongo shell处理多行操作的方式。 除非shell看到一些它认为会跨越多行的东西,否则它会一个接一个地评估行,在这种情况下,它将启动一个“多行操作”。

使用mongo命令(不用pipe道input文件),它可能看起来像这样:

 > 40 + 2; > 42 > for(var i = 0; i < 2; i++) { > ... 

在评估for循环之前,一次评估40 + 2 ,但是{将告诉mongo等待它的closures对象}

这个行为logging在这里 。

问题是/*不是这样的符号,所以mongo不会等待它的朋友*/ 。 它将等待更多的行,或者直到你给它一些它认为可以评估的东西。

 /* var categories = []; * */ ... 

上述不会抛出错误,并将继续等待进一步的指示,因为*/二元运算符,所以mongo知道没有什么好评可以来自评估一个行,在那些结束。 所以它会等待,然后如果你添加,比如说40 + 2那么它就会得到42 ,因为现在从/*40 + 2的整个评估代码是有效的JavaScript。

也许这并不是确定是否评估一个input行的最优雅的方式,但现在它是如何工作的。 相若方式,

 /* { var categories = []; var sum = 0; ...other commented stuff.. }*/ 

因为mongo会在评估之前等待结束。 但是,这可能不是你每次写评论都想做的事情,而是让下一位开发人员想知道这是不是写出文档的新方法。

解决scheme1

你可以用//单行注释。 无论是散装还是一个一个评估,至less应该没问题。 但是这会让你的代码面临一些其他相关的问题。 例如,

 var template = ` Awesome multi-line template string... ...or error? `; 

解决scheme2

如果你不想经常担心,如果事情会在shell中工作(我知道我没有),你可以改变你执行脚本的方式。

不要像mongo.exe < script.js那样将文件传输到mongo,而是使用“script.js”作为参数运行mongo命令: mongo.exe script.js

这将评估代码在“脚本”模式而不是“交互式”的,所以它将解决这些问题。 有些事情需要改变,但为了这个工作。 助手喜欢use test; 将无法在脚本模式下工作,您需要将其更改为JavaScript对应的var db = getDB('test');

这些差异logging在这里 。

避免在javascript中使用块注释/ * * /。 只使用单行注释//。

来源:Douglas Crockford-JavaScript_好的部分(2008)

JavaScript提供了两种forms的注释,用/ * * /形成的块注释和以//开头的行尾注释。 评论应该宽松地使用,以提高您的程序的可读性。 注意评论总是准确地描述代码。 过时的评论比没有评论更糟糕。

块注释的/ * * /forms来自一种称为PL / I的语言。 PL / Iselect那些奇怪的对作为注释的符号,因为它们不太可能出现在该语言的程序中,除了string文字。 在JavaScript中,这些对也可以在正则expression式文字中出现,所以阻止注释对于注释代码块是不安全的。 例如:

 /* var rm_a = /a*/.match(s); */ 

导致语法错误。 所以,build议避免使用/ * * /注释,而不要使用注释。 在这本书中,//将被独占使用。