我有 Couchdb 视图,但这并不符合我的预期。它不会将code
,balance
和session
添加到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 doc的示例:
{
"_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
}
}
答案 0 :(得分:2)
您的2个示例中的差异是initial_url_params
是已定义对象doc
的属性,在传递给您的函数之前可能已frozen。因此,您无法向其添加新属性,但您仍然可以读取并迭代这些属性以构建新的(未冻结的)对象。
根据OP的linked thread来看似乎就是这种情况。
在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
已修改它,因为对象通过引用传递。这是一种过于简单的表示,但是当函数尝试将对象的属性映射到其他逻辑时,您可以看到这可能导致的位置。