Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.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继承:使用模块模式和$.extend覆盖功能_Javascript_Jquery_Inheritance_Scope - Fatal编程技术网

Javascript继承:使用模块模式和$.extend覆盖功能

Javascript继承:使用模块模式和$.extend覆盖功能,javascript,jquery,inheritance,scope,Javascript,Jquery,Inheritance,Scope,我有以下情况,在这种情况下,我扩展父类并重写行为。但是,不会调用重写的行为 // parent scope definition (function ($) { $.extend(true, window, { Demo: { Parent: Parent } }); function Parent() { function A() { //do something } function B() { //do something else

我有以下情况,在这种情况下,我扩展父类并重写行为。但是,不会调用重写的行为

// parent scope definition
(function ($) {

 $.extend(true, window, {
  Demo: {
    Parent: Parent
  }
 });

 function Parent() {
  function A() {
    //do something
  }
  function B() {
    //do something else
    A();
  }
  // public api
  $.extend(this,{ "A":A, "B":B });
  }
})(jQuery);

// child scope definition
(function ($,parent) {

 $.extend(true, window, {
  Demo: {
    Child: Child
  }
 });

 function Child() {
  // inherit all from parent
  parent.apply(child,arguments);
  this.A = function () {
    // override parent behavior
  }
  this.B();
 }
})(jQuery,Parent);

//...somewhere else, in another scope call: var kid = new Child();
<html>
  <script>
    var kid = new Child();
  </script>
</html>
当创建一个新的子对象时,将调用B,它指向子上下文。但是,窗口的上下文将不是子窗口上下文,而是全局窗口上下文。也不会调用的重写行为

我必须使用无原型继承的模块模式,并重写超类行为

请有人告诉我如何保存上下文,以确保调用重写的行为

提前谢谢大家,, 安德烈

编辑1:我必须使用模块,希望在重写行为时尽可能少地更改父级

编辑2:为了更清楚,由于下面提供的答案,我必须为父模块/对象使用显示模块模式,并扩展/覆盖其在子模块中的行为


编辑3:问题标题和问题似乎不同,可能会产生误导:真正的核心问题是关于javascript覆盖的问题,如其中一个答案所示。确实发生的范围变化被错误地认为是真正的问题。我将从标题中删除对它的提及。更正是为了让其他人从下面的答案中受益。范围发生了变化,但这在当前的代码设计和我的调用场景中可能是正常的。忽略此问题中的方面上下文。

您可以使用bind函数

var foo = function () {
// override parent behavior
}
this.A = foo.bind(child);

在上面的代码中,bind将返回一个基于foo的新函数对象,并将其设置为child

我已按如下方式重写了您的代码,不确定这是否是您要查找的:

// No need of IEFE
function Parent() {
  this.A=function A () {
    console.log("Executing A");
  }
  this.B= function B () {
    console.log("Executing B");
    this.A();
  }

};

//again, no need of IEFE, just declaring    
function Child() {
  // inherit all from parent
  Parent.apply(this);
  this.A = function () {
    console.log("Executing the new A");
  }
  this.B();
};

var c=new Child();
console.log("Done");
控制台显示:

Executing B
Executing the new A
Done 

定义模块时

  $.extend(this,{ "A":A, "B":B });
通过在闭包中定义A和B,使用对公共成员的直接闭包引用,然后将对象文本传递给$.extend,可以隐式地使用显示模块模式。显示模块模式是基本模块模式的反模式变体,因为。如果您想要获取覆盖,一般的经验法则是尽可能多地使用它

重写您的示例以在适当的情况下使用此方法,下面的步骤应该可以做到:

(function Parent() {
  function A() {
    //do something
  }
  function B() {
    //use this!
    this.A();
  }
  // public api
  $.extend(this,{ "A":A, "B":B });
})();

(function Child() {
  // inherit all from parent
  Parent.apply(child,arguments);
  this.A = function () {
    // override parent behavior
  }
  this.B();
})();

什么是孩子?什么是自我?什么是父对象?它不在范围内?您想创建模块独立对象还是无类构造函数?如果是前者,那么超类意味着什么?如果是后者,为什么是父母和孩子?或者在哪里调用它们?@Bergi编辑;赛尔夫应该是这样的,对不起。我想创建modules.var kid=new Child;不是一个模块,而是一个构造函数?为什么不想使用原型继承呢?我只能使用模块;至少我不能对父对象使用原型继承。父级必须保持模块状态。我在哪里执行此操作?因为如果我在我的子模块构造函数类型函数中这样做,这个和子模块应该是相同的,并且我的作用域问题不会得到解决:。谢谢你的回答。至少在父级中,我必须使用$.extend。如果可能的话,不要将父模块设为A和B。@acostache:在你提出的问题中的代码中,它们是私有成员?@Bergi不,不是像Crockford所说的那样使用它。我不想使用这个,但使用显示模块pattern@acostache:使用这个有什么意义?不要相信克罗克福德。特权是在构造函数中声明的函数的一种质量,在构造函数中,它们可以访问构造函数的局部变量,然后将这些变量导出,例如,通过将它们赋给this的属性,或使用$.extend来完成导出。你的函数A和B就是那个。@Bergi好的,我的错,我没有得到那个部分。谢谢你的澄清。那么,我只是不想在父级中使用它。是否可以使用相同的设计展示模块模式来实现相同的功能,但如果没有特权成员,则没有此功能?@acostache,AFAIK,没有简单的方法可以避免使用此功能。您可以尝试以与此不同的方式传入调用上下文,但这是临时的和丑陋的。正确的做法是避免暴露模块模式,而不是这个。嗯,有没有什么好的、不一定是结构化的方法来扩展使用暴露模块模式构建的东西,以便覆盖行为?除了我们的讨论用这个来解释但丁-放弃所有扩展的希望,你们进入揭示模块模式。由于有用的讨论和建议,我将此标记为正确答案。