javascript javascript获取父嵌套对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13534153/
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-10-26 19:05:08  来源:igfitidea点击:

javascript get parent nested object?

javascriptoopobject

提问by Joe

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() ?

回答by Denys Séguret

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. You should know that the pattern I gave is more frequently used to define modules. OOP in javascript is more often done using newand prototype, in order to enable instances sharing methods and inheritance. As you probably want modules rather than OOP, you seem to be fine, though.

我看到您为您的问题提供了 OOP 标签。你应该知道我给出的模式更常用于定义模块。javascript 中的 OOP 更常使用newand来完成prototype,以启用实例共享方法和继承。因为您可能想要模块而不是 OOP,所以您似乎没问题。

See this introduction.

看到这个介绍

回答by Poindess

Here's how you can add .parentto any sub-object with a recursive init:

以下是.parent使用递归 init添加到任何子对象的方法:

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 .parentas 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

回答by Elliot B.

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 Proxiesas helpers.

但是,如果您使用递归ES6 代理作为助手,则是可能的。

I've written a library called ObservableSlimthat, among other things, allows you to traverse up from a child object to the parent.

我编写了一个名为ObservableSlim的库,除其他外,它允许您从子对象向上遍历到父对象。

Here's a simple example (jsFiddle demo):

这是一个简单的示例(jsFiddle 演示):

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

回答by hugomg

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, func3and func4directly from their variables. 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.

在这个例子中,内部功能可以访问obj1obj2func3func4从它们的变量直接。自调用函数使这些内部变量是私有的并且对外部隐藏,并且 return 语句允许您仅导出要公开的函数。

回答by Jorge Fuentes González

Here is an asnwer more ActionScriptlike 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.

请记住,一个对象不能有多个父对象。

回答by Alexander

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. 代码,正如您在我的实现中看到的那样)。

You can test it here: http://jsbin.com/eVOpITom/1/edit

你可以在这里测试:http: //jsbin.com/eVOpITom/1/edit

回答by 0x499602D2

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.func1as func1or in any way shorter. If you find yourself calling that function excessively, try setting a variable instead.

那是不可能的。对象属性由设置它们的对象获取。JavaScript 不会隐式地将根对象设置为全局对象,因此您不能将其别名obj.subobj2.func1为 asfunc1或以任何方式缩短。如果您发现自己过度调用该函数,请尝试设置一个变量。