我有一个像这样的任意深度的对象:
var uid = context.getUrlParameter("documentId");
var doc:NotesDocument = database.getDocumentByUNID(uid);
if(doc.getItemValueString("$$disabled") != "true") {
// want to return the Edit Mode
return "Edit Mode "
} else {
// do nothing
return false;
}
我调用一个将上面的const objToAccess = {
id: 1,
name: {
first: 'Foo',
last: 'Bar'
},
address: {
street: {
name: '987 Walker',
roadType: 'Ave'
},
zip: '12345'
}
};
作为参数的函数。编辑:此功能是一个黑盒子。我不知道它是什么样的,无法编辑它。例如:
objToAccess
调用该函数后,我想知道访问了哪些属性。这里是踢球者:如果访问了嵌套对象,我也希望将所有子项标记为被访问。例如,在运行上面的代码之后,我希望得到如下结果:< / p>
const accessFn = objToAccess => {
const a = objToAccess.id;
const b = objToAccess.name.first;
const c = objToAccess.address;
};
我天真的尝试是创建const propsAccessed = {
id: true,
name: {
first: true,
last: false
},
address: {
street: {
name: true,
roadType: true
},
zip: true
}
};
对象&amp;将所有内容设置为false,然后使用getter(下面)。但是,我无法弄清楚如何使用它们,如果只访问父对象,则标记所有子节点。任何想法都会很棒!
propsAccessed
答案 0 :(得分:2)
我会使用代理:
function isObject(val) {
return val === Object(val);
}
function detectAccess(obj) {
if(!isObject(obj)) return {proxy: obj, accessLog: true};
var subProxies = Object.create(null);
var accessLog = Object.create(null);
var proxy = new Proxy(obj, {
get: function(target, prop, receiver) {
if(!accessLog[prop]) {
var recur = detectAccess(obj[prop]);
accessLog[prop] = recur.accessLog;
return subProxies[prop] = recur.proxy;
} else {
return subProxies[prop];
}
}
});
return {proxy, accessLog};
}
var {proxy, accessLog} = detectAccess(objToAccess);
accessFn(proxy);
accessLog; // {id:true, name:{first:true}, address:{}}
accessLog
告诉我们访问了哪些属性。如果值是基元,则日志将包含true
,否则它将包含对象。
然后,如果您想知道例如是否已访问objToAccess.address.street.name
,请使用
!!(accessLog.address && accessLog.address.street && accessLog.address.name)
(请参阅test for existence of nested object key以避免重复所有属性路径。)
如果您想要在访问顶层对象的属性时访问所有子树,只需使用
!!(accessLog.address)