简单地说
我有一个由物体组成的树状结构。
是否可以构建该树并向每个对象添加对其父级的引用?
我知道引用适用于对象,但我不确定它是否会在这种情况下使用?
我希望能够写出像这样的东西
currentLevel = this.getParent();
另一个例子是
this.getChildList().addChild({name: test,parent: this})
没有副本并从第一个创建多个树。
第二个问题
引用如何与数组一起使用?它们被视为对象还是取决于它们的内容?
第3个问题
将树保存在浏览器的缓存中,通过string-JSON序列化来销毁引用吗?
答案 0 :(得分:2)
你可以这样做是为了创建一个“TreeNode”类:
var TreeNode = (function(){
//keep track of parent node
TreeNode.prototype.parent = null;
//keep track of children
TreeNode.prototype.children = [];
function TreeNode(parent) {
if(parent !== undefined) {
if(this.setParent(parent)) {
this.parent.addChild(this);
}
}
//...
}
TreeNode.prototype.setParent = function(parent) {
//add some sort of check to make sure it is a `TreeNode`
if(parent instanceof TreeNode) {
this.parent = parent;
return true;
}
return false;
}
TreeNode.prototype.addChild = function(child) {
//add some sort of check to make sure it is a `TreeNode`
if(child instanceof TreeNode) {
this.children.push(child);
child.setParent(this);
}
}
TreeNode.prototype.getParent = function(){
return this.parent;
}
TreeNode.prototype.getChildren = function(){
return this.children;
}
return TreeNode;
})();
然后你可以从中扩展。
示例代码:
var node_a = new TreeNode();
var node_b = new TreeNode(node_a);
var node_c = new TreeNode(node_a);
console.log(node_a.getParent(), node_c.get_parent()); //null , node_a
console.log(node_a.getChildren()); //[node_b, node_c]
这只是一个开始,它需要waaaaaaaaaay更多扩展: - )
答案 1 :(得分:2)
好的,所以最有可能的框架,但我写了一个快速的东西,支持 JSON序列化和反向(通过它自己的方法)。我从Neal的回答中得到了基础灵感。实施例
var a = new MyTreeNode('a'), // make some nodes
b = new MyTreeNode('b'),
c = new MyTreeNode('c');
a.addChild(b).addChild(c); // a parent of b parent of c
c.getParent() === b; // true
var str = a.toJSON(); // "{"nodeName":"a","childNodes":[{"nodeName":"b","childNodes":[{"nodeName":"c","childNodes":[]}]}]}"
MyTreeNode.parseJSON(str); // MyTreeNode (same structure as before)
完整代码
/* MyTreeNode(String nodeName)
Instance Properties
- nodeName, String
- childNodes, Array of MyTreeNodes
- parentNode, MyTreeNode
Instance Methods
- addChild(MyTreeNode node), child MyTreeNode
- removeChild(MyTreeNode node), child MyTreeNode
- getParent, parent MyTreeNode
- getChildList, Array of MyTreeNodes
- serialise, JSON-safe Object
- toJSON, String
Constructor Methods
- deserialise(Object serialised), MyTreeNode
- parseJSON(String JSONString), MyTreeNode
*/
var MyTreeNode = (function () {
function MyTreeNode(nodeName) {
nodeName && (this.nodeName = nodeName);
this.childNodes = [];
}
MyTreeNode.prototype.parentNode = null;
MyTreeNode.prototype.childNodes = [];
MyTreeNode.prototype.nodeName = '';
// getters
MyTreeNode.prototype.getChildList = function () {
return this.childNodes = [];
};
MyTreeNode.prototype.getParent = function () {
return this.parentNode;
};
// add/remove
MyTreeNode.prototype.removeChild = function (node) {
var i = this.childNodes.indexOf(node);
if (node.parentNode !== this || i == -1)
throw new ReferenceError('node is not a child of this');
this.childNodes.splice(i, 1);
node.parentNode = null;
return node;
};
MyTreeNode.prototype.addChild = function (node) {
if (node.parentNode) node.parentNode.removeChild(node);
node.parentNode = this;
this.childNodes.push(node);
return node;
};
// JSON
MyTreeNode.prototype.serialise = function () {
var o = {
nodeName: this.nodeName,
childNodes: []
}, i;
for (i = 0; i < this.childNodes.length; ++i) {
o.childNodes.push(this.childNodes[i].serialise());
}
return o;
};
MyTreeNode.prototype.toJSON = function () {
return JSON.stringify(this.serialise());
};
MyTreeNode.deserialise = function (o) {
var p = new MyTreeNode(o.nodeName), i;
for (i = 0; i < o.childNodes.length; ++i) {
p.addChild(MyTreeNode.deserialise(o.childNodes[i]));
}
return p;
};
MyTreeNode.parseJSON = function (str) {
var o = JSON.parse(str);
return MyTreeNode.deserialise(o);
};
return MyTreeNode;
}());
答案 2 :(得分:1)
您可以遍历您的对象并将父属性添加到每个子对象:
function addParents(obj) {
var name;
for (name in obj) {
if (typeof obj[name] === "object") {
addParents(obj[name]);
obj[name].parent = obj;
}
}
}
var obj = {
g: {
k: [
{
r : 1
},
{
r : 1
}
],
j: {
h: 1
}
}
};
addParents(obj);
console.log(obj.g.parent === obj); //true
console.log(obj.g.k.parent === obj.g); //true
console.log(obj.g.k[1].parent === obj.g.k); //true
console.log(obj.g.j.parent === obj.g); //true
如果您想稍后添加对象,可以使用以下内容:
function addChild(obj, child, name){
obj[name] = child;
child.parent = obj;
}
addChild(obj.g, {t:1}, "xy");
console.log(obj.g.xy.parent === obj.g); //true
<强> FIDDLE 强>