javascript获取父嵌套对象?
Posted
技术标签:
【中文标题】javascript获取父嵌套对象?【英文标题】:javascript get parent nested object? 【发布时间】:2012-11-12 02:49:48 【问题描述】:我有一个像这样的对象,例如:
obj =
subobj1:
,
subobj2:
func1: function()
,
func2: function()
,
subobj3:
func3: function()
,
func4: function()
,
如何从 func4 中调用 func1 而无需调用 obj.subobj2.func1() ?
【问题讨论】:
【参考方案1】:你不能完全正确。您无法知道您的函数存在于哪些对象中。
请注意,它可能不止一个:您可以在现有代码之后编写此代码:
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();
Demonstration
编辑
我看到你给你的问题加上了 OOP 标签。你应该知道我给出的模式更常用于定义模块。 javascript 中的 OOP 更经常使用 new
和 prototype
来完成,以启用实例共享方法和继承。不过,由于您可能需要模块而不是 OOP,但您似乎还不错。
见this introduction。
【讨论】:
有this.parent.func1()这样的函数吗? 您不能只在对象声明中设置变量。这不起作用 嗯,有道理,从工厂外调用 subobj2.func1 是不是必须调用 obj.that.suboj2.func1? 否:您可以直接致电obj.suboj2.func1();
。事实上parent
(上次编辑之前的“那个”)是私有的:如果它不是简单的 obj,你就不能在工厂外调用它。【参考方案2】:
以下是如何将.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
【讨论】:
这看起来是最干净的工作解决方案,我使用它并且非常喜欢它。另外,嵌套.parent
非常有用。
将属性分配给 null 时收到错误消息。修复了将 if (typeof this[i] == 'object')
替换为 if (typeof this[i] == 'object' && this[i] !== null)
【参考方案3】:
您不能直接这样做,因为没有办法像在文件系统中使用“..”那样“向上”对象层次结构。
您可以做的是让变量直接指向子对象或子函数,这样您就不需要通过层次结构来调用它们。以下是创建 Javascript 模块的常见模式:
obj = (function()
var obj1 = ...
var obj2 = ...
var func3 = function()...;
var func4 = function()...;
return
subobj1: obj1,
subobj2: obj2,
subobj3:
func3: func3,
func4: func4
());
在本例中,内部函数可以直接从它们的变量中访问obj1
、obj2
、func3
和func4
。自调用函数使这些内部变量是私有的并且对外部隐藏,并且 return 语句允许您仅导出要公开的函数。
【讨论】:
【参考方案4】:正如其他人所说,使用普通对象无法从嵌套的子对象中查找父对象。
但是,如果您使用递归 ES6 Proxies 作为助手,这是可能的。
我编写了一个名为ObservableSlim 的库,除其他外,它允许您从子对象向上遍历到父对象。
这是一个简单的例子 (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);
【讨论】:
【参考方案5】:这是不可能的。对象属性由设置它们的对象获得。 JavaScript 不会将根对象隐式设置为全局对象,因此您不能将 obj.subobj2.func1
别名为 func1
或更短。如果您发现自己过度调用该函数,请尝试设置一个变量。
【讨论】:
【参考方案6】:这里有一个更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);
请记住,一个对象不能有多个父对象。
【讨论】:
【参考方案7】:您对对象的实现是不可能的。取决于您的需求 - 以下实现可能很有用:
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. 代码,正如您在我的实现中看到的那样)。
你可以在这里测试它:http://jsbin.com/eVOpITom/1/edit
【讨论】:
以上是关于javascript获取父嵌套对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何为嵌套对象或同一父对象中的对象列表定义 GraphQLObjectType