灵活的JavaScriptfunction(适用于MongoDB)

我正在为MongoDB进行一些Map / Reduce查询,并试图完成以下内容(简而言之)。

m = function() { this.convert = function(val) { return val+1; } emit(convert(this.age), this.doesWearGlasses); } r = function(k, v) { count = 0; for(var i = 0; i < v.length; i++) { count += v[i]; } return count; } if(tuned) { m.convert = function(val) { return val; } } /** * Continue to running the M/R query */ 

应该指出,我正在写这个Node.js应用程序,但我认为大多数相同的主体适用于任何JavaScript。

问题是我不认为我可以改变它没有创build一个对象,ala mTmp = new m(); ,但我不能因为emit() (和其他一切)没有定义。

我尝试使用m.prototype.convert = function ,但这是行不通的。 m.toString()的值不会改变。

认为你正在尝试部分m (地图函数)的行为有所不同,具体取决于是否设置了tuned 。 是对的吗?

不幸的是,既然map函数和reduce函数都是以string的forms传递给MongoDB的,只是函数的主体,他们将无法访问任何外部的代码或数据 – 所以你在函数上设置的任何属性都不会存在当它被执行。

如果我正确地理解你,我认为这是你三个最好的select:

  1. 为每种情况定义不同的版本。

  2. m组合为一个string,根据tuned的值,将其放入正确的代码块中。

  3. m根据variables决定如何performance:

     m = function() { var result; if (tuned) { result = this.age; } else { result = this.age + 1; } emit(convert(this.age), this.doesWearGlasses); } 

    …当你调用mapReduce时候,给MongoDB里的第二个variables赋予tunedvariables:

     collection.mapReduce(m, r, { scope: { tuned: tuned } }); 

    (FWIW,如果不同的是,其实这个很简单,你可以这样写m

     m = function() { emit(convert(tuned ? this.age : this.age + 1), this.doesWearGlasses); } 

让我知道你的意思是不同的。

由于在定义prototype函数后调用构造函数, this.convert将覆盖已定义的原型函数。

你可以覆盖整个m构造函数:

 m = function() { this.convert = function(val) { return val+1; } } if(tuned) { m = (function(mOld) { return function() { mOld.apply(this, arguments); this.convert = function(val){ return val; } } })(m); } // Test code function doStuff(obj) { alert(obj.toString()); } var mObj = new m(); doStuff(mObj); 

它应该工作,但我不知道它可能会影响你的实际脚本。

请注意,它使用自我调用模式,它会创build一个闭包。

我已经添加了testing代码,certificate了这在OP中的约束条件下工作。