Javascript 对象:获取父对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2980763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:47:01  来源:igfitidea点击:

Javascript objects: get parent

javascript

提问by D?nu

I have the following (nested) object:

我有以下(嵌套)对象:

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

Next thing I do is to reference the subobject like this:

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

var s = obj.subObj;

Now what I would like to do is to get a reference to the object objout of the variable s. Something like:

现在我想做的是obj从变量中获取对对象的引用s。就像是:

var o = s.parent;

Is this somehow possible?

这有可能吗?

采纳答案by Matthew Flaschen

No. There is no way of knowing which object it came from.

不。没有办法知道它来自哪个对象。

sand obj.subObjboth simply have references to the same object.

s并且obj.subObj两者都只是对同一个对象的引用。

You could also do:

你也可以这样做:

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

You now have three references, obj.subObj, obj2.subObj, and s, to the same object. None of them is special.

现在,您对同一个对象有了三个引用、obj.subObjobj2.subObjs。它们都不是特别的。

回答by Mik

A nested object (child) inside another object (parent) cannot get data directly from its parent.

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

Have a look on this:

看看这个:

var main = {
    name : "main object",
    child : {
        name : "child object"
    }
};

If you ask the main object what its child name is (main.child.name) you will get it.
Instead you cannot do it vice versa because the child doesn't know who its parent is.
(You can get main.namebut you won't get main.child.parent.name).

如果你问主对象它的子名称是什么 ( main.child.name) 你会得到它。
相反,您不能反之亦然,因为孩子不知道其父母是谁。
(你可以得到,main.name但你不会得到main.child.parent.name)。

By the way, a function could be useful to solve this clue.
Let's extend the code above:

顺便说一下,一个函数可能有助于解决这个线索。
让我们扩展上面的代码:

var main = {
    name : "main object",
    child : {
        name : "child object"
    },
    init : function() {
        this.child.parent = this;
        delete this.init;
        return this;
    }
}.init();

Inside the initfunction you can get the parent object simply calling this.
So we define the parentproperty directly inside the childobject.
Then (optionally) we can remove the initmethod.
Finally we give the main object back as output from the initfunction.

init函数内部,您只需调用this.
所以我们parent直接在child对象内部定义属性。
然后(可选)我们可以删除该init方法。
最后,我们将主对象作为init函数的输出返回。

If you try to get main.child.parent.namenow you will get it right.
It is a little bit tricky but it works fine.

如果你main.child.parent.name现在就尝试,你会得到正确的。
这有点棘手,但效果很好。

回答by Nonlinearsound

This is an old question but as I came across it looking for an answer I thought I will add my answer to this to help others as soon as they got the same problem.

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

I have a structure like this:

我有这样的结构:

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

Currently, by referencing one of the sub nodes I don't know how to get the parent node with it's name value "Main Level".

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

Now I introduce a recursive function that travels the structure and adds a parent attribute to each node object and fills it with its parent like so.

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

var setParent = function(o){
     if(o.nodes != undefined){
          for(n in o.nodes){
              o.nodes[n].parent = o;
              setParent(o.nodes[n]);
          }
     }
}

Then I just call that function and can now get the parent of the current node in this object tree.

然后我只需调用该函数,现在就可以获取此对象树中当前节点的父节点。

setParent(structure.root);

If I now have a reference to the seconds sub node of root, I can just call.

如果我现在有对 root 的 seconds 子节点的引用,我可以调用。

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

and it will output "Main Level".

它将输出“主级别”。

Hope this helps..

希望这可以帮助..

回答by Steve Ladavich

Many of the answers here involve looping through an object and "manually" (albeit programmatically) creating a parent property that stores the reference to the parent. The two ways of implementing this seem to be...

这里的许多答案都涉及循环遍历一个对象并“手动”(尽管以编程方式)创建一个存储对父对象的引用的父属性。实现这一点的两种方法似乎是......

  1. Use an initfunction to loop through at the time the nested object is created, or...
  2. Supply the nested object to a function that fills out the parent property
  1. init在创建嵌套对象时使用函数循环,或者...
  2. 将嵌套对象提供给填充父属性的函数

Both approaches have the same issue...

两种方法都有相同的问题......

How do you maintain parents as the nested object grows/changes??

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

If I add a new sub-sub-object, how does it get its parent property filled? If you're (1) using an initfunction, the initialization is already done and over, so you'd have to (2) pass the object through a function to search for new children and add the appropriate parent property.

如果我添加一个新的子子对象,它如何填充其父属性?如果您 (1) 使用init函数,则初始化已经完成,因此您必须 (2) 通过函数传递对象以搜索新子项并添加适当的父属性。

Using ES6 Proxy to add parentwhenever an object/sub-object is set

使用 ES6 代理添加parent对象/子对象set

The approach below is to create a handler for a proxy always adds a parent property each time an object is set. I've called this handler the parenterhandler. The parenterresponsibilities are to recognize when an object is being set and then to...

下面的方法是为代理创建一个处理程序,每次设置对象时总是添加一个父属性。我称这个处理程序为parenter处理程序。的parenter职责是当被设定一个对象,然后以承认...

  1. Create a dummy proxy with the appropriate parentand the parenterhandler

    var p = new Proxy({parent: target}, parenter);
    
  2. Copy in the supplied objects properties-- Because you're setting the proxy properties in this loop the parenterhandler is working recursively; nested objects are given parents at each level

    for(key in value){
        p[key] = value[key];
      }
    
  3. Set the proxy not the supplied object

    return target[prop] = p;
    
  1. 使用适当的parentparenter处理程序创建一个虚拟代理

    var p = new Proxy({parent: target}, parenter);
    
  2. 复制提供的对象属性——因为你在这个循环中设置代理属性,parenter处理程序递归地工作;嵌套对象在每个级别都有父级

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

    return target[prop] = p;
    

Full code

完整代码

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"

Notice that all root children always have parent properties, even children that are added later.

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

回答by lukasz

There is a more 'smooth' solution for this :)

对此有一个更“平滑”的解决方案:)

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;

回答by Poindess

To further iterate on Mik's answer, you could also recursivey attach a parent to all nested objects.

为了进一步迭代 Mik 的答案,您还可以递归地将父对象附加到所有嵌套对象。

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

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

回答by SirPython

You could try this(this uses a constructor, but I'm sure you can change it around a bit):

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

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

回答by usr56777

I have been working on a solution to finding the parent object of the current object for my own pet project. Adding a reference to the parent object within the current object creates a cyclic relationship between the two objects.

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

Consider -

考虑 -

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

The variable obj will now look like this -

变量 obj 现在看起来像这样 -

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

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

This is not good. The only solution that I have found so far is to create a function which iterates over all the properties of the outermost Object until a match is found for the current Object and then that Object is returned.

这是不好的。到目前为止,我找到的唯一解决方案是创建一个函数,该函数迭代最外层对象的所有属性,直到找到当前对象的匹配项,然后返回该对象。

Example -

例子 -

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

Of course, without knowing or having a reference to the outermost object, there is no way to do this. This is not a practical nor is it an efficient solution. I am going to continue to work on this and hopefully find a good answer for this problem.

当然,如果不知道或没有对最外层对象的引用,就没有办法做到这一点。这既不实用,也不是有效的解决方案。我将继续研究这个问题,并希望为这个问题找到一个好的答案。

回答by Wallace

You will need the child to store the parents this variable. As the Parent is the only object that has access to it's this variable it will also need a function that places the this variable into the child's that variable, something like this.

您将需要孩子来存储父母这个变量。由于 Parent 是唯一可以访问它的 this 变量的对象,因此它还需要一个函数将 this 变量放入子级的那个变量中,就像这样。

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

To test this out try to run this in Firefox's Scratchpad, it worked for me.

为了测试这一点,尝试在 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();

回答by Trevor

Try this until a non-no answer appears:

试试这个,直到出现非否答案:

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