从JavaScript运行MongoDB命令时会执行注释代码

Bar*_*ney 14 mongodb node.js

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);
Run Code Online (Sandbox Code Playgroud)

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

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
bye

我使用以下命令/语法在windows机器中执行了JavaScript文件:

mongo.exe < script.js
Run Code Online (Sandbox Code Playgroud)

为什么我看到这些错误,即使categories变量在注释块内.

这不是一个表明,想了解它为什么会发生?

nop*_*ppa 7

这可能是由于mongo shell处理多行操作的方式.shell会逐行评估行,除非它看到它认为会跨越多行的内容,在这种情况下它会启动"多行操作".

使用该mongo命令(没有管道输入文件),它可能看起来像这样:

> 40 + 2;
> 42
> for(var i = 0; i < 2; i++) {
> ...
Run Code Online (Sandbox Code Playgroud)

哪里40 + 2被立即评估,但是在评估for循环之前{,会告诉mongo等待其结束对应物}.

此行为记录在此处.

问题是/*不是这样的符号,所以mongo不会等待它的朋友*/.它会等待一条线,或者直到你给它认为可以评估的东西.

/*
    var categories = []; *
*/
 ...
Run Code Online (Sandbox Code Playgroud)

以上不会引发错误,将继续等待进一步的指令,因为这两个*/二元运算符,以便蒙戈知道没有什么好可以来自评估,在那些结束的行.因此,它会等待,然后如果你愿意加入,也就是说,40 + 2它会屈服于42就好了,因为从现在整个评估一段代码/*40 + 2是有效的JavaScript.

也许这不是确定是否评估输入线的最优雅的方式,但现在它的工作方式.相若方式,

/* {
    var categories = [];
    var sum = 0;
    ...other commented stuff..
}*/
Run Code Online (Sandbox Code Playgroud)

会工作,因为mongo会}在评估之前等待收盘.但是,这可能不是你每次写评论时都想做的事情,而是让下一个开发人员想知道这是否是编写文档的新方法.

解决方案1

您可以使用单行注释//.至少那些应该是好的,无论是批量评估还是逐一评估.但这会使您的代码对其他一些相关问题开放.例如,

var template = `
    Awesome multi-line template string...


    ...or error?
 `;
Run Code Online (Sandbox Code Playgroud)

解决方案2

如果您不想经常担心shell中是否有效(我知道我没有),您可以改变执行脚本的方式.

取而代之的管道来蒙戈如文件mongo.exe < script.js,用"的script.js"作为参数运行蒙戈命令:mongo.exe script.js.

这将以"脚本"模式而不是"交互式"模式评估代码,因此它将解决这些问题.有些事情需要改变才能实现.助手use test;不会在脚本模式下工作,您需要将其更改为JavaScript对应物var db = getDB('test');.

这些差异在此处记录.


小智 5

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

\n\n

资料来源:Douglas Crockford-JavaScript_ The Good Parts (2008)

\n\n
\n

JavaScript 提供两种形式的注释,以 /* */ 形成的块注释和以 // 开头的 \n 行结束注释。应大量使用注释来提高程序的可读性。请注意,注释始终准确地描述代码。过时的评论比没有评论更糟糕。

\n\n

/* */ 形式的块注释来自一种名为 PL/I 的语言。\n PL/I 选择这些奇怪的对作为注释符号,因为\n 它们不太可能出现在该语言的\xe2\x80\x99s 程序中,除了\n 可能在字符串文字中。在 JavaScript 中,这些对也可能出现在正则表达式文字中,因此块注释对于注释掉代码块来说并不安全。例如:

\n
\n\n
/*\nvar rm_a = /a*/.match(s);\n*/\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

导致语法错误。因此,建议避免使用 /* */ 注释,而使用 // 注释。在本书中,将专门使用//。

\n
\n