4

我有这个Couchdb视图,它没有达到我的预期。它不添加code,balancesessionto params

function(doc) {
    var params = doc.initial_url_params; //This is an object with many properties
    params["code"] = doc.code;
    params["balance"] = doc.balance;
    params["session"] = doc.session.session_id;
    emit(doc.code, params);
}

另一方面,这个其他实现可以解决问题:

function(doc) {
    var params = {};
    params["code"] = doc.code;
    params["balance"] = doc.balance;
    params["session"] = doc.session.session_id;
    for (prop in doc.initial_url_params) {
        params[prop] = doc.initial_url_params[prop];
    }
    emit(doc.code, params);
}

谁能告诉我为什么这两个实现不等价?我是在用 Javascript 做一些愚蠢的事情,还是 Couchdb 的 Javascript 实现的一些特定限制?

为清楚起见。这是一个示例 json 文档:

{
   "_id": "207112eaaad136dca7b0b7b1c6356dc4",
   "_rev": "3-e02de1f2f269642df98ab19ee023569b",
   "session_loaded": true,
   "balance": 20.48,
   "code": "05428",
   "initial_url_params": {
       "page_id": "212"
   },
   "session": {
       "session_id": "207112eaaad136dca7b0b7b1c6356dc4",
       "init": true
   }
}
4

1 回答 1

2

您的 2 个样本的不同之处在于,它initial_url_params是一个已定义对象的属性,在传递给您的函数之前doc可能已被冻结。因此,您无法向其中添加新属性,但您仍然可以读取和迭代这些属性以构建新的(解冻的)对象。

根据 OP 的链接线程,这似乎是这种情况。


在 JavaScript 中,对象是通过引用传递的,因此如果要向doc对象添加属性,则对其进行操作的所有其他函数也将能够看到这些非标准属性并可能破坏一些映射函数。

这是上面段落的一个普通 JS 示例:

var doc = { foo: true };
function a(doc) { doc.bar = 1; }
function b(doc) { console.log(doc); }
a(doc);
b(doc); // outputs: { foo: true, bar: 1 }

Demo - 在上面的例子中,b期望只看到最初定义的属性doc,但是a已经修改了它,因为对象是通过引用传递的。这是一个过于简单的表示,但是当一个函数试图将对象的属性映射到其他逻辑时,您可以看到这可能会导致什么。

于 2013-03-01T23:20:34.040 回答