代码之家  ›  专栏  ›  技术社区  ›  Dänu

Javascript对象:get parent[duplicate]

  •  111
  • Dänu  · 技术社区  · 16 年前

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

    下一步我要做的是像这样引用子对象:

    var s = obj.subObj;
    

    obj 超出变量 s . 比如:

    var o = s.parent;
    

    这有可能吗?

    12 回复  |  直到 9 年前
        1
  •  80
  •   Matthew Flaschen    15 年前

    不,没有办法知道它来自哪个物体。

    s 和 obj.subObj

    你也可以这样做:

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

    对象subObj , obj2.subObj s ,指向同一对象。它们都不是特别的。

        2
  •  128
  •   Mik    14 年前

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

    看看这个:

    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
    然后(可选)我们可以移除 初始化
    初始化 功能。

    main.child.parent.name 现在你会明白的。

        3
  •  48
  •   Nonlinearsound    13 年前

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

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

    输出“主电平”。

        4
  •  25
  •   Steve Ladavich    10 年前

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

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

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

    如何在嵌套对象增长/更改时维护父对象??

    初始化 函数,则初始化已经完成并结束,因此必须(2)通过函数传递对象以搜索新的子对象并添加相应的父属性。

    使用ES6代理添加 parent set

    下面的方法是为代理创建一个处理程序,每次设置对象时总是添加一个父属性。我把这个人叫做 parenter 处理程序。这个 父母

    1. 使用适当的 以及 父母 处理程序

      var p = new Proxy({parent: target}, parenter);
      
    2. 在提供的对象属性中复制-- 因为你在这个循环中设置代理属性

      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"
    

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

        5
  •  8
  •   lukasz    14 年前

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

    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;
    
        6
  •  6
  •   Poindess    12 年前

    为了进一步迭代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

        7
  •  4
  •   SirPython    11 年前

    function Obj() {
        this.subObj = {
            // code
        }
        this.subObj.parent = this;
    }
    
        8
  •  3
  •   usr56777    10 年前

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

    考虑-

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

    变量obj现在如下所示-

    对象。内部对象。父对象。内部对象。父对象。内部对象。。。

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

    示例-

    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
    

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

        9
  •  2
  •   Trevor    15 年前

    尝试此操作直到出现非“否”答案:

    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);
    
        10
  •  2
  •   Wallace    11 年前

    您将需要子级来存储此变量的父级。因为父对象是唯一有权访问它的这个变量的对象,所以它还需要一个函数将这个变量放入子对象的那个变量中,类似这样的。

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

    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();
    
        11
  •  0
  •   axius    12 年前

    只是将父值保留在子属性中

    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);
    
        12
  •  0
  •   Sean ar.gorgin    11 年前

    当我加载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中某个对象的父对象