Javascript对象:得到父母

我有以下(嵌套)的对象:

obj: { subObj: { foo: 'hello world' } }; 

接下来我要做的就是像这样引用子对象:

 var s = obj.subObj; 

现在我想要做的是从variabless获取对象obj的引用。 就像是:

 var o = s.parent; 

这有可能吗?

不,不知道它来自哪个对象。

sobj.subObj都只是对同一个对象的引用。

你也可以这样做:

 var obj = { subObj: {foo: 'hello world'} }; var obj2 = {}; obj2.subObj = obj.subObj; var s = obj.subObj; 

您现在有三个引用, obj.subObjobj2.subObjs ,对同一个对象。 没有一个是特别的。

另一个对象(父对象)中的嵌套对象(子对象)不能直接从其父对象中获取数据。

看看这个:

 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父对象。
所以我们直接在child对象中定义parent属性。
然后(可选)我们可以删除init方法。
最后我们把主对象作为init函数的输出。

如果您现在尝试获取main.child.parent.name那么您将得到正确的结果。
这是有点棘手,但它工作正常。

这是一个古老的问题,但当我遇到它寻找一个答案,我想我会加我的答案,以帮助其他人,一旦他们得到同样的问题。

我有这样的结构:

 var structure = { "root":{ "name":"Main Level", nodes:{ "node1":{ "name":"Node 1" }, "node2":{ "name":"Node 2" }, "node3":{ "name":"Node 3" } } } } 

目前,通过引用其中一个子节点,我不知道如何获得名称为“Main Level”的父节点。

现在我介绍一个遍历结构的recursion函数,并为每个节点对象添加一个父属性,并像这样填充它的父项。

 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); 

如果我现在有一个参考根节点的子节点,我可以打电话。

 var node2 = structure.root.nodes["node2"]; console.log(node2.parent.name); 

并输出“Main Level”。

希望这可以帮助..

这里的许多答案都涉及遍历对象和“手动”(尽pipe以编程方式)创build一个存储对父对象的引用的父属性。 实施这两种方法似乎是…

  1. 使用init函数在创build嵌套对象时循环,或者…
  2. 将嵌套对象提供给填充父属性的函数

两种方法都有同样的问题…

随着嵌套对象的增长/变化,你如何维护父母?

如果我添加一个新的子子对象,它是如何获得其父属性填充? 如果(1)使用init函数,初始化已经完成,所以你必须(2)通过函数传递对象来search新的子项并添加适当的父属性。

只要设置了对象/子对象,就可以使用ES6 Proxy来添加parent

下面的方法是为代理创build一个处理程序,每次设置一个对象时总会添加一个父属性。 我已经把这个处理程序叫做parenter处理程序。 承担责任是识别何时设置对象,然后…

  1. 用合适的parentparent处理程序创build一个虚拟代理

     var p = new Proxy({parent: target}, parenter); 
  2. 在提供的对象属性中复制 – 因为你要在这个循环中设置代理属性,所以parenter处理器正在recursion地工作; 嵌套的对象被赋予每个级别的父母

     for(key in value){ p[key] = value[key]; } 
  3. 设置代理不是提供的对象

     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" 

请注意,所有根子项都始终具有父项属性,甚至是稍后添加的子项。

有一个更平滑的解决scheme:)

 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; 

为了进一步迭代Mik的答案,你也可以recursion地将父项附加到所有的嵌套对象上。

 var myApp = { init: function() { for (var i in this) { if (typeof this[i] == 'object') { this[i].init = this.init; this[i].init(); this[i].parent = this; } } return this; }, obj1: { obj2: { notify: function() { console.log(this.parent.parent.obj3.msg); } } }, obj3: { msg: 'Hello' } }.init(); myApp.obj1.obj2.notify(); 

http://jsbin.com/zupepelaciya/1/watch?js,console

你可以尝试这个(这使用了一个构造函数,但是我相信你可以改变它):

 function Obj() { this.subObj = { // code } this.subObj.parent = this; } 

试试这个,直到出现一个非答案。

 function parent() { this.child; interestingProperty = "5"; ... } function child() { this.parent; ... } a = new parent(); a.child = new child(); a.child.parent = a; // this gives the child a reference to its parent alert(a.interestingProperty+" === "+a.child.parent.interestingProperty); 

您需要孩子将这个variables存储在父母身上。 由于Parent是唯一可以访问它的对象,所以它也需要一个函数把这个variables放到子variables中,像这样。

 var Parent = { Child : { that : {}, }, init : function(){ this.Child.that = this; } } 

为了testing这个,试着在Firefox的Scratchpad中运行它,它为我工作。

 var Parent = { data : "Parent Data", Child : { that : {}, data : "Child Data", display : function(){ console.log(this.data); console.log(this.that.data); } }, init : function(){ this.Child.that = this; } } Parent.init(); Parent.Child.display(); 

我一直在寻找一个解决scheme,为我自己的宠物项目find当前对象的父对象。 在当前对象中添加对父对象的引用会在两个对象之间创build循环关系。

考虑 –

 var obj = { innerObj: {}, setParent: function(){ this.innerObj.parent = this; } }; obj.setParent(); 

variablesobj现在看起来像这样 –

obj.innerObj.parent.innerObj.parent.innerObj …

不是很好。 目前为止唯一的解决scheme是创build一个迭代最外层对象的所有属性的函数,直到find当前对象的匹配,然后返回该对象。

示例 –

 var obj = { innerObj: { innerInnerObj: {} } }; var o = obj.innerObj.innerInnerObj, found = false; var getParent = function (currObj, parObj) { for(var x in parObj){ if(parObj.hasOwnProperty(x)){ if(parObj[x] === currObj){ found = parObj; }else if(typeof parObj[x] === 'object'){ getParent(currObj, parObj[x]); } } } return found; }; var res = getParent(o, obj); // res = obj.innerObj 

当然,如果不知道或没有参考最外层的对象,就没有办法做到这一点。 这不是一个实际的也不是一个有效的解决scheme。 我将继续努力解决这个问题,希望能find一个很好的答案。

只是保持父属性值的子属性

 var Foo = function(){ this.val= 4; this.test={}; this.test.val=6; this.test.par=this; } var myObj = new Foo(); alert(myObj.val); alert(myObj.test.val); alert(myObj.test.par.val); 

当我加载一个JSON对象时,我通常通过像这样迭代对象数组来设置关系:

  for (var i = 0; i < some.json.objectarray.length; i++) { var p = some.json.objectarray[i]; for (var j = 0; j < p.somechildarray.length; j++) { p.somechildarray[j].parent = p; } } 

那么你可以通过使用.parent来访问somechildarray中某个对象的父对象