7

例如,我有一个这样的对象:

obj = {
    subobj1: {

    },
    subobj2: {
        func1: function(){

        },
        func2: function(){

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

        },
        func4: function(){

        }        
    },
}

如何从 func4 中调用 func1 而不必调用 obj.subobj2.func1() ?

4

7 回答 7

15

你不能完全。您无法知道您的函数存在于哪些对象中。

请注意,它可能不止一个:您可以在现有代码之后编写此代码:

var obj2 = {some:obj.subobj3};

因此,从属性值到持有它的对象之间不可能有唯一的链接(也没有可访问的链接)。

现在,假设您对创建对象时的链接感到满意,您可以使用工厂来构建您的对象:

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

        },
        subobj2: {
            func1: function(){

            },
            func2: function(){

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

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

然后你可以打电话

obj.subobj3.func4();

示范


编辑

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

请参阅此介绍

于 2012-11-23T18:24:13.520 回答
6

以下是使用递归初始化添加.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();

使用此解决方案,您还可以.parent根据嵌套需要多次使用,例如,如果您有两层嵌套:

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

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

于 2014-10-14T21:18:25.750 回答
1

您不能直接这样做,因为没有办法像在文件系统中使用“..”那样“向上”对象层次结构。

您可以做的是让变量直接指向子对象或子函数,这样您就不需要通过层次结构来调用它们。以下是创建 Javascript 模块的常见模式:

obj = (function(){

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

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

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

在此示例中,内部函数可以直接从其变量中访问obj1obj2和。自调用函数使这些内部变量是私有的并且对外部隐藏,并且 return 语句允许您仅导出要公开的函数。func3func4

于 2012-11-23T18:36:46.407 回答
1

正如其他人所说,使用普通对象是不可能从嵌套的孩子中查找父母的。

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

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

这是一个简单的示例(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);
于 2018-01-25T08:18:28.063 回答
0

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

于 2012-11-23T18:36:19.063 回答
0

这是一个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);

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

于 2013-07-03T16:06:04.833 回答
0

您对对象的实现是不可能的。取决于您的需求 - 以下实现可能有用:

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

这个想法是嵌套对象不能知道谁是他们的父母,但父母可以告诉它的孩子他是谁(但是然后需要init.code,正如你在我的实现中看到的那样)。

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

于 2014-01-23T12:42:54.330 回答