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,没有简单的方法可以避免使用此功能。您可以尝试以与此不同的方式传入调用上下文,但这是临时的和丑陋的。正确的做法是避免暴露模块模式,而不是这个。嗯,有没有什么好的、不一定是结构化的方法来扩展使用暴露模块模式构建的东西,以便覆盖行为?除了我们的讨论用这个来解释但丁-放弃所有扩展的希望,你们进入揭示模块模式。由于有用的讨论和建议,我将此标记为正确答案。