你需要記住,函數是在JavaScript中的一等公民。
我看,基本上你有什麼是一樣的東西
function createVisitor(parentsAccumulatorInitialValue, parentsAccumulator){
var visitor = function myVisitor (node) {
var result;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
result.push(thisPath);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}
result = [];
listForNode(node, parentsAccumulatorInitialValue());
return result;
}
return visitor;
}
var listPaths = createVisitor(
function parentInit() {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});
但是,這不是你能照顧唯一的抽象:
function createVisitor2(
totalAccumulatorInitialValue,
totalAccumulator,
parentsAccumulatorInitialValue,
parentsAccumulator){
var visitor = function myVisitor (node) {
var total;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
total = totalAccumulator(total, thisPath, n);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}
total = totalAccumulatorInitialValue();
listForNode(node, parentsAccumulatorInitialValue());
return total;
}
return visitor;
}
var listPaths2 = createVisitor2(
function totalInit() {
return [];
},
function totalAcc(total, thisPath, n){
total.push(thisPath);
return total;
},
function parentInit() {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});
這可能是相當合理的,但你可以看,我已經開始難以找到這些變量的適當名稱。事實上,我會說我們的函數的名稱是不好的,因爲它不會像我所瞭解的訪客對象那樣嚴格地創建任何東西。然而,它的工作(順便說一句,我稍微修改它來處理空值以及空數組):
> listPaths({ path:"foo",
childs: [{path:"bar", childs: null}, {path:"bob", childs: null}]})
["/foo", "/foo/bar", "/foo/bob"]
它甚至可以進一步進行修改,這樣你的樹木不嚴格,甚至具有相同的結構...但我們已經在4個參數,這不是很好。如果您的訪問者創建者傳遞了具有所有必要方法或值的單個可擴展對象,那將會更好。例如,也許(僞代碼):
function createVisitor3(opts) {
//assume we've defined GetDefaults() somewhere local to createVisitor3
// as well as assume that extend is defined somewhere that copies properties
// into a new object like various previously existing libraries do.
opts = extend({}, GetDefaults(), opts);
var totalAccumulatorInitialValue = opts.totalAccumulatorInitialValue;
var totalAccumulator = opts.totalAccumulator;
var parentsAccumulatorInitialValue = opts.parentsAccumulatorInitialValue;
var parentsAccumulator = opts.parentsAccumulator;
var childrenGetter = opts.childrenGetter;
/// etc.
...
}
您能否更詳細地解釋一下您試圖實現的「可嘲笑」方面?我想我正在試圖理解600和600行代碼測試文件是如何相關的。是否有關於JS對象上沒有方法被調用的事實,所以很難嘲笑遞歸樹訪問函數? –