Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从嵌套对象函数调用JavaScript函数失败_Javascript - Fatal编程技术网

从嵌套对象函数调用JavaScript函数失败

从嵌套对象函数调用JavaScript函数失败,javascript,Javascript,在下面的简单示例和这里的JSFIDLE上,您可以看到我的问题 我可以理解为什么会发生这种情况,但我不知道如何在保持JS结构不变的情况下修复它 问题是,当我定义一个JavaScript对象原型函数时,我有一个第二级嵌套对象,它有一个函数,在该函数中,我调用父/根级别的函数,但失败了 下面代码中的此函数This.nestedObject.nested\u object\u function()尝试调用函数This.normal\u function(),但失败并显示: Uncaught TypeEr

在下面的简单示例和这里的JSFIDLE上,您可以看到我的问题

我可以理解为什么会发生这种情况,但我不知道如何在保持JS结构不变的情况下修复它

问题是,当我定义一个JavaScript对象原型函数时,我有一个第二级嵌套对象,它有一个函数,在该函数中,我调用父/根级别的函数,但失败了

下面代码中的此函数
This.nestedObject.nested\u object\u function()
尝试调用函数
This.normal\u function()
,但失败并显示:

Uncaught TypeError: this.normal_function is not a function
    at Object.nested_object_function (VM2493:79)
我假设原因是
this
引用的是
this.nestedObject
,而不是父对象

如果是这样的话,那么我如何像调用嵌套对象函数那样调用该函数并调用父函数呢

我还尝试调用
JsLibTest.normal\u function()
作为来自
this.nestedObject.nested\u object\u function()
函数的测试,但我得到了相同的错误


var JsLibTest=(函数(文档){
“严格使用”;
var JsLibTest=函数(){
//启动新的JsLibTest对象时运行init()函数
this.init();
};
/**
*JsLibTest原型函数
*/
JsLibTest.prototype={
init:function(){
//正如预期的那样,此函数运行良好
这个.normal_函数();
//嵌套级别对象函数从父级别对象函数运行fune
此.nestedObject.nested_object_函数();
},
正规函数:函数(){
log('this.normal_function()run');
},
嵌套对象:{
//从该嵌套对象函数调用时,在父对象上调用函数在此处失败
嵌套的对象函数:函数(){
这个.normal_函数();
log('this.nestedObject.nested_object_function()ran');
},
}
};
返回JsLibTest;
})(文件);
//运行它
$(文档).ready(函数(){
var Sidebar2=新的JsLibTest();
});

首先,每个对象都必须是唯一的,具有一个原型:

this.nestedObject=Object.create(this.nestedObject);

var JsLibTest = function (){
      // run init() function on initiation of a new JsLibTest object
      this.init();
      //bind to childs:
      this.nestedObject.parent=this;
    };
现在您可以在内部函数中使用this.parent

this.parent.normal_function();
如果要将其作为父对象,请绑定:

var JsLibTest = function (){
      // run init() function on initiation of a new JsLibTest object
      this.init();
      //bind to childs:
      for(i in this.nestedObject){
         var el=this.nestedObject[i];
         if(typeof el==="function"){
             this.nestedObject[i]=el.bind(this);
         }
       }
    };
为了方便起见,可以使用这样的东西(助手函数):

这样使用:

JsLibTestInstance("nestedObject","nestedobject_function")();

你的评估是正确的
将被设置为嵌套对象而不是父对象,这就是为什么它说函数是
未定义的

您需要的是引用父对象的方式。对象通常不携带引用它们的对象所需的任何信息。当考虑到许多对象可以在内部引用同一个对象的事实时,这是有意义的。 可以存储对父对象的引用,也可以在嵌套函数中存储对该父对象的引用:

getfunc:function(...a){
  a.reduce((obj,key)=>obj[key],this).bind(this);
}
var嵌套={
g(){
this.parent.f();
}
};
变量父项={
f(){
log('called');
}
};
nested.parent=父项;

嵌套的.g()
是的,
JSLibTest.prototype.nestedObject
函数中的
this
值指向
nestedObject
而不是JSLibTest,这是对的

如果要维护相同的调用签名,可以将
nestedObject
声明为IIFE:

nestedObject: (function() {
  var that = this;

  return {
    nested_object_function: function() {
      console.log(that);
      //    this.normal_function();
      alert('this.nestedObject.nested_object_function() ran');
    }
  }
}())

注意:您可能不想声明您的
prototype
,因为这样可以有效地删除对象的所有原生prototype方法

以类似的方式编写代码,考虑使用<代码>对象。赋值< /代码>帮助您。

var foo = Object.assign({}, Function.prototype, {
  bar() {
    console.log("Hello!")
  }
});

foo.bar();

您认为作用域没有访问父级的权限是正确的。简单的解决方案是将父对象传递给嵌套对象,如:

this.nestedObject.nested_object_function(this);
然后在嵌套函数中,将父函数调用为:

nested_object_function: function(self) {
    self.normal_function();
    alert('this.nestedObject.nested_object_function() ran');
}

由于您将此(父级)作为self传递,因此可以从嵌套的一个调用它。

感谢您的多次演示,最后一个解决方案似乎是我的最佳解决方案。另外,我有许多大型JS应用程序正在工作,现在使用相同的JS设计,所以你的答案将修复我的许多问题!谢谢大家!@杰森达维太棒了!我很高兴能为您提供帮助:)您的
bar()
示例与
Object.assign
是否需要为对象上的每个函数运行整个代码?