简体   繁体   English

javascript获取父嵌套对象?

[英]javascript get parent nested object?

I have an object like this for example: 我有一个这样的对象,例如:

obj = {
    subobj1: {

    },
    subobj2: {
        func1: function(){

        },
        func2: function(){

        }
    },
    subobj3: {
        func3: function(){

        },
        func4: function(){

        }        
    },
}

How do I call func1 from within func4 without having to call obj.subobj2.func1() ? 如何在func4中调用func1而不必调用obj.subobj2.func1()?

You can't exactly. 你不能完全。 You have no mean to know in what objects your function exists. 你无意知道你的函数存在于哪些对象中。

Note that it could be in more than one : you could have written this after your existing code : 请注意,它可能不止一个:您可以在现有代码之后编写:

var obj2 = {some:obj.subobj3};

So there can't be a unique link (and there is no accessible link) from a property value to the object holding it. 因此,从属性值到持有它的对象不能有唯一的链接(并且没有可访问的链接)。

Now, supposing you'd be satisfied with a link made at object creation, you could use a factory to build your object : 现在,假设您对在对象创建时创建的链接感到满意,您可以使用工厂来构建对象:

obj = (function(){
    var parent = {
        subobj1: {

        },
        subobj2: {
            func1: function(){

            },
            func2: function(){

            }
        },
        subobj3: {
            func3: function(){

            },
            func4: function(){
                parent.subobj2.func1();
            }        
        }
    };
    return parent;
})();

Then you can call 然后你可以打电话

obj.subobj3.func4();

Demonstration 示范


EDIT 编辑

I see you gave the tag OOP to your question. 我看到你给你的问题标记OOP了。 You should know that the pattern I gave is more frequently used to define modules. 您应该知道我给出的模式更常用于定义模块。 OOP in javascript is more often done using new and prototype , in order to enable instances sharing methods and inheritance. javascript中的OOP通常使用newprototype来完成,以便实现实例共享方法和继承。 As you probably want modules rather than OOP, you seem to be fine, though. 因为你可能想要模块而不是OOP,但你看起来很好。

See this introduction . 这个介绍

Here's how you can add .parent to any sub-object with a recursive init: 以下是使用递归init将.parent添加到任何子对象的方法:

var obj = {
    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;
    },
    subobj1: {
    },
    subobj2: {
        func1: function(){
            console.log('hey');
        },
        func2: function(){
        }
    },
    subobj3: {
        func3: function(){
        },
        func4: function(){
            this.parent.subobj2.func1();
        }        
    }
}.init();

obj.subobj3.func4();

With this solution you can also use .parent as many times as your nesting requires, like for instance if you had two levels of nesting: 使用此解决方案,您还可以像嵌套一样多次使用.parent ,例如,如果您有两个嵌套级别:

this.parent.parent.subobjX.funcY();

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

As others have said, with a plain object it is not possible to lookup a parent from a nested child. 正如其他人所说,使用普通对象,无法从嵌套子项中查找父项。

However, it is possible if you employ recursive ES6 Proxies as helpers. 但是,如果您使用递归ES6代理作为帮助程序,则可能。

I've written a library called ObservableSlim that, among other things, allows you to traverse up from a child object to the parent. 我编写了一个名为ObservableSlim的库,除其他外,它允许您从子对象遍历到父对象。

Here's a simple example ( jsFiddle demo ): 这是一个简单的例子( jsFiddle demo ):

var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function(changes) {
    console.log(JSON.stringify(changes));
});

function traverseUp(childObj) {
    console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}}
    console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object
};

traverseUp(proxy.hello.foo);

That isn't possible. 那是不可能的。 Object properties are obtain by the object through which they are set. 对象属性由设置它们的对象获取。 JavaScript doesn't implicitly set the root object as global, and therefore you can't alias obj.subobj2.func1 as func1 or in any way shorter. JavaScript不会将根对象隐式设置为全局,因此您不能将obj.subobj2.func1别名为func1或以任何方式缩短。 If you find yourself calling that function excessively, try setting a variable instead. 如果您发现自己过度调用该函数,请尝试设置变量。

You can't do that directly, since there is no way to "go up" the object hierarchy like you can with ".." in a filesystem. 你不能直接这样做,因为没有办法像文件系统中的“..”一样“上升”对象层次结构。

What you can do is have variables pointing to the subobjects or subfunctions directly, so that you don't need to go through the hierarchy to call them. 您可以做的是直接指向子对象或子函数的变量,这样您就不需要通过层次结构来调用它们。 The following is a common pattern for creating Javascript modules: 以下是创建Javascript模块的常见模式:

obj = (function(){

    var obj1 = {...}
    var obj2 = {...}

    var func3 = function(){...};
    var func4 = function(){...};

    return {
        subobj1: obj1,
        subobj2: obj2,
        subobj3: {
            func3: func3,
            func4: func4
        }
    }
}());

In this example, the inner functions can access obj1 , obj2 , func3 and func4 directly from their variables. 在此示例中,内部函数可以直接从其变量访问obj1obj2func3func4 The self-calling function makes so these inner variables are private and hidden from the outside and the return statement allows you to export only the functions that you want to make public. 自调用函数使得这些内部变量是私有的并且从外部隐藏,而return语句允许您仅导出要公开的函数。

Here is an asnwer more ActionScript like and easily to understand: 以下是一个更容易理解的ActionScript

function MainObject() {
   this.x = 100;
   this.y = 50;
   this.second = new SecondObject(this);
}

function SecondObject(p) {
    this.parent = p;
}

var firstobject = new MainObject();

// Saving a reference to SecondObject.
var secondObject = firstobject.second;

// Because of parent variable, you can access second object parent without needing to have the parent object in a variable.
console.log(secondObject.parent.x);
console.log(secondObject.parent.y);

Just remember that an object can't have multiple parents. 请记住,一个对象不能有多个父对象。

It's impossible with your implementation of the object. 你实现这个对象是不可能的。 Depends on your needs - the following implementation could be useful: 取决于您的需求 - 以下实施可能有用:

obj = function(){
  var obj = {
    subobj1: {

    },
    subobj2: {
        func1: function(){
          console.log('func1');
        },
        func2: function(){

        }
    },
    subobj3: {
        func3: function(){

        },
        func4: function(){
          this.parentObject.subobj2.func1();
        }        
    }
  }
  obj.subobj3.parentObject = obj;
/*  
  //You can also init parentObject reference of the rest of the nested objects if you need
  obj.subobj1.parentObject = obj;
  obj.subobj2.parentObject = obj;
*/  
  return obj;
}();

obj.subobj3.func4();

The idea is that nested objects can't know who is their parent, but the parent can tell its children who is he (but then init. code is needed as you can see in my implementation). 这个想法是嵌套对象不能知道谁是他们的父对象,但是父对象可以告诉它的子对象是谁(但是在我的实现中你可以看到init.code是必需的)。

You can test it here: http://jsbin.com/eVOpITom/1/edit 你可以在这里测试一下: http//jsbin.com/eVOpITom/1/edit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM