我对如何在 mongodb shell 中使用闭包感到困惑。
我想创建一个函数,我可以在开发期间独占使用通过它的一部分_id
快速查找文档。
该函数应该返回一个 $where
选择器来进行必要的匹配。
我想这样写:
var id = function(pattern, selector) {
return Object.extend({
$where: function() {return (this._id + "").indexOf(pattern) != -1;}
}, selector);
};
但是当我尝试它时,出现以下错误:
db.mycollection.find(id("ab1"));
error: {
"$err" : "JavaScript execution failed: ReferenceError: pattern is not defined near ').indexOf(pattern) ' ",
"code" : 16722
}
手动调用 $where
似乎很奇怪:
id("ell").$where.call({_id: "hello"}); // true
我只能将其视为使其工作的解决方案,但这显然很糟糕。
需要澄清的是:这种带有 new Function
的方法工作正常,但我不喜欢它,因为上面的方法应该也能工作。
var id = function(pattern, selector){
return Object.extend({
$where: new Function("return (this._id + '').indexOf('" + pattern + "') != -1;")
}, selector);
};
- 为什么我的闭包不起作用,闭包在 mongodb shell 中有效吗?
- 奖励问题:我可以在用户配置文件中的某处注册此功能以自动加载吗?
最佳答案
似乎 MongoDB shell 序列化(在本例中为字符串化)$where
函数对象,以便将它们发送到服务器。
JavaScript 中的函数不仅仅是它的功能代码——它是 closure 的一部分,其中包括函数代码本身 和函数的变量引用环境,用于访问非局部变量。函数序列化后,它会反序列化并在不同的引用环境中执行。当函数尝试引用 pattern
时,它要求 pattern
在一个完全不同的引用环境中,它没有 pattern
变量。
这就是您的文字字符串函数起作用的原因。该函数包含 pattern
的实际值,不是变量标识符 pattern
.
参见 this MongoDB bug ,这解释了:
That would work if the function was being evaluated locally, but the closure isn't sent over automatically.
In babble it used to be, but not in the shell.
这表明您的代码可能在 shell 之外工作,但我对 Mongo 内部的了解还不够多,无法确定。
关于javascript - 如何在 mongodb shell 中使用闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17405531/