注意:JS中对基本类型的赋值那就是赋值,对于object类型(非基本类型)所有的赋值(包括 push函数)全部为引用。
function convert(rows){
// 功能函数,没特殊的
function exists(rows, parentId){
for(var i=0; i<rows.length; i++){
if (rows[i].id == parentId) return true;
}
return false;
}
// nodes这个数组是最后的返回值
// 这段代码是找出所有的顶级节点:所有父亲节点不在完整列表中的为顶级节点(也就是找不到父亲的)
var nodes = [];
// get the top level nodes
for(var i=0; i<rows.length; i++){
var row = rows[i];
if (!exists(rows, row.parentId)){
// 这里的 push 是赋值不是引用,除了这里操作了 nodes[] 数组,下面的代码没有任何地方直接使用nodes[]数组
nodes.push({
id:row.id,
text:row.name
});
}
}
// 这里的 toDo 是开辟了新的存储空间的用来存放数据
var toDo = [];
for(var i=0; i<nodes.length; i++){
// 这里push的元素为 nodes中的元素的引用
// 这里没有做 toDo = nodes,所以即使是保存的有 nodes中元素的引用,toDo 是一个独立的数组,toDo不是nodes的引用
toDo.push(nodes[i]);
}
while(toDo.length){
// 删除了首个元素,将nodes中的引用从toDo数组中删除了,返回值为被删除的节点
// node 变量 为 nodes 数组的引用,所以才能改变了notes[]数组的值!!!!
var node = toDo.shift(); // the parent node
// get the children nodes
for(var i=0; i<rows.length; i++){
var row = rows[i];
if (row.parentId == node.id){
var child = {id:row.id,text:row.name};
if (node.children){
// 这里是赋值,改变了notes[]数组
node.children.push(child);
} else {
// 这里是赋值,改变了notes[]数组
node.children = [child];
}
//这里添加的是引用
toDo.push(child);
}
}
}
return nodes;
}