从javascript对象访问父级的父级

时间:2022-05-27 23:05:51

Something like

就像是

var life= {
        users : {
             guys : function(){ this.SOMETHING.mameAndDestroy(this.girls); },
             girls : function(){ this.SOMETHING.kiss(this.boys); },
        },
        mameAndDestroy : function(group){ },
        kiss : function(group){ }
};

this.SOMETHING is what I imagine the format is, but it might not be. What will step back up to the parent of an object?

这个.SOMETHING是我想象的格式,但它可能不是。什么会退回到对象的父级?

11 个解决方案

#1


37  

JavaScript does not offer this functionality natively. And I doubt you could even create this type of functionality. For example:

JavaScript本身不提供此功能。我怀疑你甚至可以创建这种类型的功能。例如:

var Bobby = {name: "Bobby"};
var Dad = {name: "Dad", children: [ Bobby ]};
var Mom = {name: "Mom", children: [ Bobby ]};

Who does Bobby belong to?

鲍比属于谁?

#2


54  

I simply added in first function

我只是添加了第一个函数

parentThis = this;

and use parentThis in subfunction. Why? Because in JavaScript, objects are soft. A new member can be added to a soft object by simple assignment (not like ie. Java where classical objects are hard. The only way to add a new member to a hard object is to create a new class) More on this here: http://www.crockford.com/javascript/inheritance.html

并在子功能中使用parentThis。为什么?因为在JavaScript中,对象很软。可以通过简单的赋值将新成员添加到软对象中(不像是经典对象很难的Java。将新成员添加到硬对象的唯一方法是创建一个新类)更多相关内容:http ://www.crockford.com/javascript/inheritance.html

And also at the end you don't have to kill or destroy the object. Why I found here: http://bytes.com/topic/javascript/answers/152552-javascript-destroy-object

而且最后你不必杀死或破坏对象。为什么我在这里找到:http://bytes.com/topic/javascript/answers/152552-javascript-destroy-object

Hope this helps

希望这可以帮助

#3


19  

In this case, you could use life to reference the parent object. Or you could store a reference to life in the users object. There can't be a fixed parent available to you in the language, because users is just a reference to an object, and there could be other references...

在这种情况下,您可以使用life来引用父对象。或者您可以在users对象中存储对生命的引用。在该语言中没有可用的固定父级,因为用户只是对对象的引用,并且可能有其他引用...

var death = { residents : life.users };
life.users.smallFurryCreaturesFromAlphaCentauri = { exist : function() {} };
// death.residents.smallFurryCreaturesFromAlphaCentauri now exists
//  - because life.users references the same object as death.residents!

You might find it helpful to use something like this:

你可能会发现使用这样的东西很有帮助:

function addChild(ob, childName, childOb)
{
   ob[childName] = childOb;
   childOb.parent = ob;
}

var life= {
        mameAndDestroy : function(group){ },
        kiss : function(group){ }
};

addChild(life, 'users', {
   guys : function(){ this.parent.mameAndDestroy(this.girls); },
   girls : function(){ this.parent.kiss(this.boys); },
   });

// life.users.parent now exists and points to life

#4


4  

If I'm reading your question correctly, objects in general are agnostic about where they are contained. They don't know who their parents are. To find that information, you have to parse the parent data structure. The DOM has ways of doing this for us when you're talking about element objects in a document, but it looks like you're talking about vanilla objects.

如果我正确地阅读你的问题,那么一般来说对象都不知道它们被包含在哪里。他们不知道他们的父母是谁。要查找该信息,您必须解析父数据结构。当你在谈论文档中的元素对象时,DOM有为我们这样做的方法,但看起来你在谈论的是vanilla对象。

#5


4  

About Call:

You can sort of solve this issue by using .call() which:

您可以使用.call()来解决此问题:

  • must be called on a function addName.call()
  • 必须在函数addName.call()上调用
  • you pass it an object of what you want to be the "this" addName.call({"name" : 'angela'});
  • 你把它想要成为“this”的对象传递给addName.call({“name”:'angela'});
  • you can pass additional arguments that can be used in the function it is called on addName.call({"name": "angela"}, true); where perhaps addName accepts an argument of boolean append.
  • 你可以传递可以在addName.call调用的函数中使用的其他参数({“name”:“angela”},true);也许addName接受boolean append的参数。

Use Call:

For this particular problem, we can pass the "parent" object through call to override the this normally present in the child object.

对于这个特殊问题,我们可以通过调用传递“父”对象来覆盖通常存在于子对象中的这个。

Look at our problem first

var app = {
    init: function() {
        var _this = this; // so we can access the app object in other functions

        $('#thingy').click(function(){
            alert(_this.options.thingy());
        });

        $('#another').click(function(){
            alert(_this.options.getAnother());
        });
    },
    options: {
      thingy: function() {
      // PROBLEM: the this here refers to options
        return this.getThingy();
      },
      getAnother: function() {
        // PROBLEM 2: we want the this here to refer to options,
        // but thingy will need the parent object
        return 'another ' + this.thingy();
      },
    },
    getThingy: function() {
        return 'thingy';
    }
};

Now, here's a solution use call

And JSFIDDLE to see it work.

并且JSFIDDLE看到它的工作原理。

var app = {
    init: function() {
        var _this = this; // so we can access the app object in other functions

        $('#thingy').click(function(){
            // SOLUTION: use call to pass _this as the 'this' used by thingy
            alert(_this.options.thingy.call(_this));
        });

        $('#another').click(function(){
            // SOLUTION 2: Use call to pass parent all the way through
            alert(_this.options.getAnother.call(_this)); 
        });
    },
    options: {
      thingy: function() {
        // SOLUTION in action, the this is the app object, not options.
        return this.getThingy(); 
      },
      getAnother: function() {
        // SOLUTION 2 in action, we can still access the options 
        // AND pass through the app object to the thingy method.
        return 'another ' + this.options.thingy.call(this); 
      },
    },
    getThingy: function() {
        return 'thingy';
    }
};

In conclusion

You can use .call() whenever you use a method on a property of your main object: app.options.someFunction(arg) should always be called with .call - app.options.someFunction.call(this, arg); - that way you can ensure that you'll always have access to every part of the object. It could give you access to another property's methods like app.helpers.anotherFunction().

每当在主对象的属性上使用方法时,都可以使用.call():应始终使用.call调用app.options.someFunction(arg) - app.options.someFunction.call(this,arg); - 通过这种方式,您可以确保始终可以访问对象的每个部分。它可以让您访问另一个属性的方法,如app.helpers.anotherFunction()。

A good idea is in the somefunction, store this in a variable _parentThis so it's obvious what the this reflects.

一个好主意是在somefunction中,将它存储在一个变量_parentThis中,因此很明显这反映了什么。

#6


3  

Here you go:

干得好:

var life={
        users:{
             guys:function(){ life.mameAndDestroy(life.users.girls); },
             girls:function(){ life.kiss(life.users.guys); }
        },
        mameAndDestroy : function(group){ 
          alert("mameAndDestroy");
          group();
        },
        kiss : function(group){
          alert("kiss");
          //could call group() here, but would result in infinite loop
        }
};

life.users.guys();
life.users.girls();

Also, make sure you don't have a comma after the "girls" definition. This will cause the script to crash in IE (any time you have a comma after the last item in an array in IE it dies).

另外,请确保在“girls”定义之后没有逗号。这将导致脚本在IE中崩溃(任何时候你在IE中的数组中的最后一项之后有逗号它就会死掉)。

See it run

看它运行

#7


1  

I used something that resembles singleton pattern:

我使用了类似单身模式的东西:

function myclass() = {
    var instance = this;

    this.Days = function() {
        var days = ["Piątek", "Sobota", "Niedziela"];
        return days;
    }

    this.EventTime = function(day, hours, minutes) {
        this.Day = instance.Days()[day];
        this.Hours = hours;
        this.minutes = minutes;
        this.TotalMinutes = day*24*60 + 60*hours + minutes;
    }
}

#8


1  

As others have said, it is not possible to directly lookup a parent from a nested child. All of the proposed solutions advise various different ways of referring back to the parent object or parent scope through an explicit variable name.

正如其他人所说,不可能直接从嵌套子项中查找父项。所有提出的解决方案都建议通过显式变量名称引用回父对象或父范围的各种不同方式。

However, directly traversing up to the the parent object is possible if you employ recursive ES6 Proxies on the parent object.

但是,如果在父对象上使用递归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演示):

var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function() { return false });

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

#9


0  

I have done something like this and it works like a charm.

我做过这样的事情,它就像一个魅力。

Simple.

简单。

P.S. There is more the the object but I just posted the relevant part.

附:对象更多,但我刚刚发布了相关部分。

var exScript = (function (undefined) {
    function exScript() {
        this.logInfo = [];
        var that = this;
        this.logInfo.push = function(e) {
            that.logInfo[that.logInfo.length] = e;
            console.log(e);
        };
    }
})();

#10


0  

With the following code you can access the parent of the object:

使用以下代码,您可以访问对象的父级:

var Users = function(parent) {
    this.parent = parent;
};
Users.prototype.guys = function(){ 
    this.parent.nameAndDestroy(['test-name-and-destroy']);
};
Users.prototype.girls = function(){ 
    this.parent.kiss(['test-kiss']);
};

var list = {
    users : function() {
        return new Users(this);
    },
    nameAndDestroy : function(group){ console.log(group); },
    kiss : function(group){ console.log(group); }
};

list.users().guys(); // should output ["test-name-and-destroy"]
list.users().girls(); // should output ["test-kiss"]

I would recommend you read about javascript Objects to get to know how you can work with Objects, it helped me a lot. I even found out about functions that I didn't even knew they existed.

我建议你阅读有关javascript对象的内容,以了解如何使用Objects,它对我帮助很大。我甚至发现了我甚至不知道它们存在的功能。

#11


0  

If you want get all parents key of a node in a literal object ({}), you can to do that:

如果要获取文字对象({})中节点的所有父键,可以这样做:

(function ($) {
    "use strict";

    $.defineProperties($, {
        parentKeys: {
            value: function (object) {
                var
                    traces = [],
                    queue = [{trace: [], node: object}],

                    block = function () {
                        var
                            node,
                            nodeKeys,
                            trace;

                        // clean the queue
                        queue = [];
                        return function (map) {
                            node = map.node;
                            nodeKeys = Object.keys(node);

                            nodeKeys.forEach(function (nodeKey) {
                                if (typeof node[nodeKey] == "object") {
                                    trace = map.trace.concat(nodeKey);
                                    // put on queue
                                    queue.push({trace: trace, node: node[nodeKey]});

                                    // traces.unshift(trace);
                                    traces.push(trace);
                                }
                            });
                        };
                    };

                while(true) {
                    if (queue.length) {
                        queue.forEach(block());
                    } else {
                        break;
                    }
                }

                return traces;
            },

            writable: true
        }

    });

})(Object);

This algorithm uses the FIFO concept for iterate the graphs using the BFS method. This code extend the class Object adding the static method parentKeys that expects a literal Object (hash table - associative array...) of the Javacript, as parameter.

该算法使用FIFO概念使用BFS方法迭代图形。此代码扩展了类Object,添加了静态方法parentKeys,它将Javacript的文字对象(哈希表 - 关联数组...)作为参数。

I hope I have helped.

我希望我有所帮助。

#1


37  

JavaScript does not offer this functionality natively. And I doubt you could even create this type of functionality. For example:

JavaScript本身不提供此功能。我怀疑你甚至可以创建这种类型的功能。例如:

var Bobby = {name: "Bobby"};
var Dad = {name: "Dad", children: [ Bobby ]};
var Mom = {name: "Mom", children: [ Bobby ]};

Who does Bobby belong to?

鲍比属于谁?

#2


54  

I simply added in first function

我只是添加了第一个函数

parentThis = this;

and use parentThis in subfunction. Why? Because in JavaScript, objects are soft. A new member can be added to a soft object by simple assignment (not like ie. Java where classical objects are hard. The only way to add a new member to a hard object is to create a new class) More on this here: http://www.crockford.com/javascript/inheritance.html

并在子功能中使用parentThis。为什么?因为在JavaScript中,对象很软。可以通过简单的赋值将新成员添加到软对象中(不像是经典对象很难的Java。将新成员添加到硬对象的唯一方法是创建一个新类)更多相关内容:http ://www.crockford.com/javascript/inheritance.html

And also at the end you don't have to kill or destroy the object. Why I found here: http://bytes.com/topic/javascript/answers/152552-javascript-destroy-object

而且最后你不必杀死或破坏对象。为什么我在这里找到:http://bytes.com/topic/javascript/answers/152552-javascript-destroy-object

Hope this helps

希望这可以帮助

#3


19  

In this case, you could use life to reference the parent object. Or you could store a reference to life in the users object. There can't be a fixed parent available to you in the language, because users is just a reference to an object, and there could be other references...

在这种情况下,您可以使用life来引用父对象。或者您可以在users对象中存储对生命的引用。在该语言中没有可用的固定父级,因为用户只是对对象的引用,并且可能有其他引用...

var death = { residents : life.users };
life.users.smallFurryCreaturesFromAlphaCentauri = { exist : function() {} };
// death.residents.smallFurryCreaturesFromAlphaCentauri now exists
//  - because life.users references the same object as death.residents!

You might find it helpful to use something like this:

你可能会发现使用这样的东西很有帮助:

function addChild(ob, childName, childOb)
{
   ob[childName] = childOb;
   childOb.parent = ob;
}

var life= {
        mameAndDestroy : function(group){ },
        kiss : function(group){ }
};

addChild(life, 'users', {
   guys : function(){ this.parent.mameAndDestroy(this.girls); },
   girls : function(){ this.parent.kiss(this.boys); },
   });

// life.users.parent now exists and points to life

#4


4  

If I'm reading your question correctly, objects in general are agnostic about where they are contained. They don't know who their parents are. To find that information, you have to parse the parent data structure. The DOM has ways of doing this for us when you're talking about element objects in a document, but it looks like you're talking about vanilla objects.

如果我正确地阅读你的问题,那么一般来说对象都不知道它们被包含在哪里。他们不知道他们的父母是谁。要查找该信息,您必须解析父数据结构。当你在谈论文档中的元素对象时,DOM有为我们这样做的方法,但看起来你在谈论的是vanilla对象。

#5


4  

About Call:

You can sort of solve this issue by using .call() which:

您可以使用.call()来解决此问题:

  • must be called on a function addName.call()
  • 必须在函数addName.call()上调用
  • you pass it an object of what you want to be the "this" addName.call({"name" : 'angela'});
  • 你把它想要成为“this”的对象传递给addName.call({“name”:'angela'});
  • you can pass additional arguments that can be used in the function it is called on addName.call({"name": "angela"}, true); where perhaps addName accepts an argument of boolean append.
  • 你可以传递可以在addName.call调用的函数中使用的其他参数({“name”:“angela”},true);也许addName接受boolean append的参数。

Use Call:

For this particular problem, we can pass the "parent" object through call to override the this normally present in the child object.

对于这个特殊问题,我们可以通过调用传递“父”对象来覆盖通常存在于子对象中的这个。

Look at our problem first

var app = {
    init: function() {
        var _this = this; // so we can access the app object in other functions

        $('#thingy').click(function(){
            alert(_this.options.thingy());
        });

        $('#another').click(function(){
            alert(_this.options.getAnother());
        });
    },
    options: {
      thingy: function() {
      // PROBLEM: the this here refers to options
        return this.getThingy();
      },
      getAnother: function() {
        // PROBLEM 2: we want the this here to refer to options,
        // but thingy will need the parent object
        return 'another ' + this.thingy();
      },
    },
    getThingy: function() {
        return 'thingy';
    }
};

Now, here's a solution use call

And JSFIDDLE to see it work.

并且JSFIDDLE看到它的工作原理。

var app = {
    init: function() {
        var _this = this; // so we can access the app object in other functions

        $('#thingy').click(function(){
            // SOLUTION: use call to pass _this as the 'this' used by thingy
            alert(_this.options.thingy.call(_this));
        });

        $('#another').click(function(){
            // SOLUTION 2: Use call to pass parent all the way through
            alert(_this.options.getAnother.call(_this)); 
        });
    },
    options: {
      thingy: function() {
        // SOLUTION in action, the this is the app object, not options.
        return this.getThingy(); 
      },
      getAnother: function() {
        // SOLUTION 2 in action, we can still access the options 
        // AND pass through the app object to the thingy method.
        return 'another ' + this.options.thingy.call(this); 
      },
    },
    getThingy: function() {
        return 'thingy';
    }
};

In conclusion

You can use .call() whenever you use a method on a property of your main object: app.options.someFunction(arg) should always be called with .call - app.options.someFunction.call(this, arg); - that way you can ensure that you'll always have access to every part of the object. It could give you access to another property's methods like app.helpers.anotherFunction().

每当在主对象的属性上使用方法时,都可以使用.call():应始终使用.call调用app.options.someFunction(arg) - app.options.someFunction.call(this,arg); - 通过这种方式,您可以确保始终可以访问对象的每个部分。它可以让您访问另一个属性的方法,如app.helpers.anotherFunction()。

A good idea is in the somefunction, store this in a variable _parentThis so it's obvious what the this reflects.

一个好主意是在somefunction中,将它存储在一个变量_parentThis中,因此很明显这反映了什么。

#6


3  

Here you go:

干得好:

var life={
        users:{
             guys:function(){ life.mameAndDestroy(life.users.girls); },
             girls:function(){ life.kiss(life.users.guys); }
        },
        mameAndDestroy : function(group){ 
          alert("mameAndDestroy");
          group();
        },
        kiss : function(group){
          alert("kiss");
          //could call group() here, but would result in infinite loop
        }
};

life.users.guys();
life.users.girls();

Also, make sure you don't have a comma after the "girls" definition. This will cause the script to crash in IE (any time you have a comma after the last item in an array in IE it dies).

另外,请确保在“girls”定义之后没有逗号。这将导致脚本在IE中崩溃(任何时候你在IE中的数组中的最后一项之后有逗号它就会死掉)。

See it run

看它运行

#7


1  

I used something that resembles singleton pattern:

我使用了类似单身模式的东西:

function myclass() = {
    var instance = this;

    this.Days = function() {
        var days = ["Piątek", "Sobota", "Niedziela"];
        return days;
    }

    this.EventTime = function(day, hours, minutes) {
        this.Day = instance.Days()[day];
        this.Hours = hours;
        this.minutes = minutes;
        this.TotalMinutes = day*24*60 + 60*hours + minutes;
    }
}

#8


1  

As others have said, it is not possible to directly lookup a parent from a nested child. All of the proposed solutions advise various different ways of referring back to the parent object or parent scope through an explicit variable name.

正如其他人所说,不可能直接从嵌套子项中查找父项。所有提出的解决方案都建议通过显式变量名称引用回父对象或父范围的各种不同方式。

However, directly traversing up to the the parent object is possible if you employ recursive ES6 Proxies on the parent object.

但是,如果在父对象上使用递归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演示):

var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function() { return false });

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

#9


0  

I have done something like this and it works like a charm.

我做过这样的事情,它就像一个魅力。

Simple.

简单。

P.S. There is more the the object but I just posted the relevant part.

附:对象更多,但我刚刚发布了相关部分。

var exScript = (function (undefined) {
    function exScript() {
        this.logInfo = [];
        var that = this;
        this.logInfo.push = function(e) {
            that.logInfo[that.logInfo.length] = e;
            console.log(e);
        };
    }
})();

#10


0  

With the following code you can access the parent of the object:

使用以下代码,您可以访问对象的父级:

var Users = function(parent) {
    this.parent = parent;
};
Users.prototype.guys = function(){ 
    this.parent.nameAndDestroy(['test-name-and-destroy']);
};
Users.prototype.girls = function(){ 
    this.parent.kiss(['test-kiss']);
};

var list = {
    users : function() {
        return new Users(this);
    },
    nameAndDestroy : function(group){ console.log(group); },
    kiss : function(group){ console.log(group); }
};

list.users().guys(); // should output ["test-name-and-destroy"]
list.users().girls(); // should output ["test-kiss"]

I would recommend you read about javascript Objects to get to know how you can work with Objects, it helped me a lot. I even found out about functions that I didn't even knew they existed.

我建议你阅读有关javascript对象的内容,以了解如何使用Objects,它对我帮助很大。我甚至发现了我甚至不知道它们存在的功能。

#11


0  

If you want get all parents key of a node in a literal object ({}), you can to do that:

如果要获取文字对象({})中节点的所有父键,可以这样做:

(function ($) {
    "use strict";

    $.defineProperties($, {
        parentKeys: {
            value: function (object) {
                var
                    traces = [],
                    queue = [{trace: [], node: object}],

                    block = function () {
                        var
                            node,
                            nodeKeys,
                            trace;

                        // clean the queue
                        queue = [];
                        return function (map) {
                            node = map.node;
                            nodeKeys = Object.keys(node);

                            nodeKeys.forEach(function (nodeKey) {
                                if (typeof node[nodeKey] == "object") {
                                    trace = map.trace.concat(nodeKey);
                                    // put on queue
                                    queue.push({trace: trace, node: node[nodeKey]});

                                    // traces.unshift(trace);
                                    traces.push(trace);
                                }
                            });
                        };
                    };

                while(true) {
                    if (queue.length) {
                        queue.forEach(block());
                    } else {
                        break;
                    }
                }

                return traces;
            },

            writable: true
        }

    });

})(Object);

This algorithm uses the FIFO concept for iterate the graphs using the BFS method. This code extend the class Object adding the static method parentKeys that expects a literal Object (hash table - associative array...) of the Javacript, as parameter.

该算法使用FIFO概念使用BFS方法迭代图形。此代码扩展了类Object,添加了静态方法parentKeys,它将Javacript的文字对象(哈希表 - 关联数组...)作为参数。

I hope I have helped.

我希望我有所帮助。