我有以下(嵌套)对象:
obj: { subObj: { foo: 'hello world' } };
接下来我要做的是像这样引用子对象:
var s = obj.subObj;
现在我想做的是obj
从变量中获取对对象的引用s
。就像是:
var o = s.parent;
这有可能吗?
我有以下(嵌套)对象:
obj: { subObj: { foo: 'hello world' } };
接下来我要做的是像这样引用子对象:
var s = obj.subObj;
现在我想做的是obj
从变量中获取对对象的引用s
。就像是:
var o = s.parent;
这有可能吗?
另一个对象(父对象)内的嵌套对象(子对象)无法直接从其父对象获取数据。
看看这个:
var main = {
name : "main object",
child : {
name : "child object"
}
};
如果你问主对象它的子名称是什么 ( main.child.name
) 你会得到它。
相反,您不能反之亦然,因为孩子不知道其父母是谁。
(你可以得到,main.name
但你不会得到main.child.parent.name
)。
顺便说一下,一个函数可能有助于解决这个线索。
让我们扩展上面的代码:
var main = {
name : "main object",
child : {
name : "child object"
},
init : function() {
this.child.parent = this;
delete this.init;
return this;
}
}.init();
在init
函数内部,您只需调用this
.
所以我们parent
直接在child
对象内部定义属性。
然后(可选)我们可以删除该init
方法。
最后,我们将主对象作为init
函数的输出返回。
如果你main.child.parent.name
现在就努力,你就会得到它。
这有点棘手,但效果很好。
不。没有办法知道它来自哪个对象。
s
并且obj.subObj
两者都只是对同一个对象的引用。
你也可以这样做:
var obj = { subObj: {foo: 'hello world'} };
var obj2 = {};
obj2.subObj = obj.subObj;
var s = obj.subObj;
您现在拥有对同一对象的三个引用、obj.subObj
、obj2.subObj
和s
。它们都不是特别的。
这是一个老问题,但当我遇到它寻找答案时,我想我会添加我的答案以帮助其他人,一旦他们遇到同样的问题。
我有这样的结构:
var structure = {
"root":{
"name":"Main Level",
nodes:{
"node1":{
"name":"Node 1"
},
"node2":{
"name":"Node 2"
},
"node3":{
"name":"Node 3"
}
}
}
}
目前,通过引用子节点之一,我不知道如何获取名称值为“Main Level”的父节点。
现在我介绍一个递归函数,它遍历结构并向每个节点对象添加一个父属性,并像这样用它的父对象填充它。
var setParent = function(o){
if(o.nodes != undefined){
for(n in o.nodes){
o.nodes[n].parent = o;
setParent(o.nodes[n]);
}
}
}
然后我只需调用该函数,现在就可以获取此对象树中当前节点的父节点。
setParent(structure.root);
如果我现在有对 root 的 seconds 子节点的引用,我可以调用。
var node2 = structure.root.nodes["node2"];
console.log(node2.parent.name);
它将输出“主级别”。
希望这可以帮助..
这里的许多答案都涉及循环遍历一个对象并“手动”(尽管以编程方式)创建一个存储对父级的引用的父级属性。实现这一点的两种方法似乎是......
init
在创建嵌套对象时使用函数循环,或者...两种方法都有相同的问题......
随着嵌套对象的增长/变化,您如何维护父母?
如果我添加一个新的子子对象,它如何填充其父属性?如果您 (1) 使用init
函数,则初始化已经完成,因此您必须 (2) 通过函数传递对象以搜索新子项并添加适当的父属性。
使用 ES6 代理添加parent
对象/子对象set
下面的方法是为代理创建一个处理程序,每次设置对象时总是添加一个父属性。我称这个处理程序为parenter
处理程序。的parenter
职责是当被设定一个对象,然后以承认...
使用适当的parent
和parenter
处理程序创建一个虚拟代理
var p = new Proxy({parent: target}, parenter);
复制提供的对象属性——因为你在这个循环中设置代理属性,parenter
处理程序递归地工作;嵌套对象在每个级别都有父级
for(key in value){
p[key] = value[key];
}
设置代理而不是提供的对象
return target[prop] = p;
完整代码
var parenter = {
set: function(target, prop, value){
if(typeof value === "object"){
var p = new Proxy({parent: target}, parenter);
for(key in value){
p[key] = value[key];
}
return target[prop] = p;
}else{
target[prop] = value;
}
}
}
var root = new Proxy({}, parenter);
// some examples
root.child1 = {
color: "red",
value: 10,
otherObj: {
otherColor: "blue",
otherValue: 20
}
}
// parents exist/behave as expected
console.log(root.child1.color) // "red"
console.log(root.child1.otherObj.parent.color) // "red"
// new children automatically have correct parent
root.child2 = {color: "green", value3: 50};
console.log(root.child2.parent.child1.color) // "red"
// changes are detected throughout
root.child1.color = "yellow"
console.log(root.child2.parent.child1.color) // "yellow"
请注意,所有根子项始终具有父属性,即使是稍后添加的子项。
对此有一个更“平滑”的解决方案:)
var Foo = function(){
this.par = 3;
this.sub = new(function(t){ //using virtual function to create sub object and pass parent object via 't'
this.p = t;
this.subFunction = function(){
alert(this.p.par);
}
})(this);
}
var myObj = new Foo();
myObj.sub.subFunction() // will popup 3;
myObj.par = 5;
myObj.sub.subFunction() // will popup 5;