Javascript继承:用模块模式和$.extend覆盖功能
Javascript inheritance: overriding functionality with module pattern and $.extend
我有以下情况,在这种情况下,我扩展父类并重写行为。但是,不会调用被覆盖的行为。
// 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>
当创建一个新的Child对象时,B将被调用,"this"指向Child上下文。然而,A的上下文不是Child,而是全局(窗口)上下文。A的重写行为也不会被调用。
我必须使用模块模式(没有原型继承),并覆盖"超类"行为。
有没有人能让我知道我如何"保留"上下文,以确保被覆盖的行为被调用。
提前谢谢你,安德烈。
edit #1:我必须使用模块(并希望在重写行为时尽可能少地更改"父")
edit #2:为了更清晰,感谢下面提供的答案,我必须对Parent
模块/对象使用"揭示模块模式",并在Child
中扩展/覆盖其行为。
edit #3:似乎问题标题和问题是不同的,可能会误导:处理和回答的问题是真正的核心问题是关于javascript在(揭示)模块模式的上下文中重写(如其中一个答案所示)。范围的变化(确实发生了)被错误地认为是真正的问题。我要把它从标题中去掉。这样做是为了让其他人从下面的答案中受益。这里有一个范围变化,但在当前的代码设计和我的调用场景中,这可能是正常的。在这个问题中忽略这一方面
当你定义你的模块
$.extend(this,{ "A":A, "B":B });
通过在闭包中定义A和B,使用对"public"成员的直接闭包引用,然后将对象文字传递给$.extend
,隐式地使用了揭示模块模式。揭示模块模式是基本模块模式的反模式变体,因为该变体无法获取覆盖。如果您想获取覆盖,一般的经验法则是尽可能多地使用this
。
在适当的地方重写您的示例以使用this
,下面应该可以达到目的:
(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();
})();
我重写了你的代码如下,不确定这是否是你正在寻找的:
// 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
可以使用bind函数
var foo = function () {
// override parent behavior
}
this.A = foo.bind(child);
在上面的代码中,bind将返回一个基于foo的新函数对象,并将this设置为child
- 在循环中分配json值时,值被覆盖
- 谷歌地图固定位置覆盖
- 只覆盖箭头键滚动事件
- JQuery覆盖不更改单选选项
- 如何覆盖锚点元素's href目标,并在我点击转到目标javascript时删除其他错误
- 将添加一个相同类型的事件附加或覆盖以前添加的具有相同名称的事件
- 传单中如何在更改基层时启用/禁用覆盖层
- 点击(右键点击)使用传单地图库获取图像覆盖的像素坐标
- HTML/CSS-用于拖放的全页面覆盖
- 让javascript知道epub3电子书中何时播放媒体覆盖
- 覆盖函数中的函数
- 无法覆盖CSS伪元素:before
- 如何覆盖原型中的事件侦听器
- 覆盖在赢得'不允许点击下面的标记,谷歌地图api v3
- 如何覆盖主干中的extend方法
- jQuery无法处理覆盖
- qoxdoo的代码覆盖工具
- jQuery$.extend,而不覆盖目标属性
- 使用下划线's.extend(..)而不覆盖某些目的地's成员
- Javascript继承:用模块模式和$.extend覆盖功能