从javascript对象访问父级的父级

时间:2008-10-08 16:36:52

标签: javascript oop

这样的东西
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是我想象的格式,但它可能不是。什么将退回到对象的父级?

11 个答案:

答案 0 :(得分:55)

我只是添加了第一个函数

parentThis = this;

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

最后,你不必杀死或摧毁对象。为什么我在这里找到:http://www.crockford.com/javascript/inheritance.html

希望这有帮助

答案 1 :(得分:42)

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

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

鲍比属于谁?

答案 2 :(得分:19)

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

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!

您可能会发现使用以下内容很有帮助:

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

答案 3 :(得分:4)

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

答案 4 :(得分:4)

关于电话:

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

    必须在函数addName.call() 上调用
  • 你传递了一个你想成为“这个”addName.call({"name" : 'angela'});
  • 的对象
  • 你可以传递可以在addName.call({"name": "angela"}, true);上调用的函数中使用的其他参数,其中addName可能接受布尔append的参数。

使用呼叫:

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

首先看看我们的问题

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';
    }
};

现在,这是一个解决方案使用调用

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';
    }
};

总结

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

一个好主意是somefunction,将this存储在变量_parentThis中,因此显而易见this反映的内容。

答案 5 :(得分:3)

你走了:

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

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

See it run

答案 6 :(得分:2)

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

但是,如果在父对象上使用递归ES6 Proxies,则可以直接遍历父对象。

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

这是一个简单的例子(jsFiddle demo):

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

答案 7 :(得分:1)

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

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 :(得分:0)

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

简单。

P.S。对象更多,但我刚刚发布了相关部分。

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

答案 9 :(得分:0)

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

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"]

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

答案 10 :(得分:0)

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

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

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

我希望我有所帮助。