Javascript 继承覆盖
Javascript Inheritance Overriding
网络上有很多关于 Javascript 覆盖的令人困惑的文献。但是,我还没有找到任何一个可以满足我的需要。我正在尝试启用继承和方法覆盖,但是是以一种特定的方式。
想象一下:
var A = function(amount) {
this.amount = amount;
var _this = this;
this.method1 = function() {
some_asynchronous_function(this.amount, function(result) {
_this.method2(result);
});
};
//The function we want to override!
this.method2 = function(result) {
do_stuff(result);
};
};
var B = function(amount) {
this.method2 = function(result) {
do_different_stuff(result);
};
A.call(this, amount);
};
B.prototype = Object.create(A.prototype);
我的目标是能够保留 A
class 中的所有内容,但 this.method2
除外。但是,当我在我的代码中实例化 B
并调用 B.method1
时,它会从 A
执行 method2
。有没有办法将我保留的内容与 Javascript 混合搭配?
这证明了您问题的本质:
var A = function() {
this.m1 = function(){ console.log('hi from m1 from A'); };
this.m2 = function(){ console.log('hi from m2 from A'); };
};
var B = function() {
this.m2 = function(){ console.log('hi from m2 from B'); };
A.call(this); //try swapping this with the previous line
};
(new B()).m2();
您在构造函数中将方法定义为实例属性。
由于您在 m2
定义之后创建 A
构造函数 运行,并且构造函数有自己的 m2
定义,因此它将覆盖它之前的定义。
此处没有有效的原型。
不过,您应该为此使用原型。
如果您将这些方法定义为实例属性,它们将分别为每个实例重新定义 new
。
如果将这些方法定义移至原型,代码将得到重用:
var A = function() {
};
A.prototype.m1 = function(){ console.log('hi from m1 from A'); };
A.prototype.m2 = function(){ console.log('hi from m2 from A'); };
var B = function() {
A.call(this);
};
B.prototype = Object.create(A.prototype);
B.prototype.m2 = function(){ console.log('hi from m2 from B'); };
(new B()).m2();
(new B()).m1();
之后,原型继承真的很简单:
- 实例methods/attributes覆盖它们是原型祖先
- 在原型中找到的属性会覆盖在原型的原型(等等)中找到的属性
- 所有写入都转到实例(
instance.attr
= 42 不会覆盖原型中的属性,而是会在 instance
上创建一个新属性 属性)
你需要原型继承,像这样:
var A = function (){
this.init.apply(this, arguments);
};
A.prototype = Object.create(Object.prototype, {
amount: null,
init: function (amount){
this.amount = amount;
},
method1: function() {
some_asynchronous_function(this.amount, this.method2.bind(this));
},
method2: function(result) {
do_stuff(result);
};
});
var B = function (){
this.init.apply(this, arguments);
};
B.prototype = Object.create(A.prototype, {
method2: function(result) {
do_different_stuff(result);
}
});
注意:Object.create 并非在每个环境中都有第二个参数。
大部分js框架都或多或少的支持继承,选一个吧。如果你想创建自己的,那么我已经实现了一个扩展功能here,也许你可以使用一些想法。
如果您的 A class 有太多行(例如超过 50 条)或方法(超过 10 条)或它违反了 class 方法 2 的替代方法=12=]。但我想这些东西对你来说并不重要。
网络上有很多关于 Javascript 覆盖的令人困惑的文献。但是,我还没有找到任何一个可以满足我的需要。我正在尝试启用继承和方法覆盖,但是是以一种特定的方式。
想象一下:
var A = function(amount) {
this.amount = amount;
var _this = this;
this.method1 = function() {
some_asynchronous_function(this.amount, function(result) {
_this.method2(result);
});
};
//The function we want to override!
this.method2 = function(result) {
do_stuff(result);
};
};
var B = function(amount) {
this.method2 = function(result) {
do_different_stuff(result);
};
A.call(this, amount);
};
B.prototype = Object.create(A.prototype);
我的目标是能够保留 A
class 中的所有内容,但 this.method2
除外。但是,当我在我的代码中实例化 B
并调用 B.method1
时,它会从 A
执行 method2
。有没有办法将我保留的内容与 Javascript 混合搭配?
这证明了您问题的本质:
var A = function() {
this.m1 = function(){ console.log('hi from m1 from A'); };
this.m2 = function(){ console.log('hi from m2 from A'); };
};
var B = function() {
this.m2 = function(){ console.log('hi from m2 from B'); };
A.call(this); //try swapping this with the previous line
};
(new B()).m2();
您在构造函数中将方法定义为实例属性。
由于您在 m2
定义之后创建 A
构造函数 运行,并且构造函数有自己的 m2
定义,因此它将覆盖它之前的定义。
此处没有有效的原型。
不过,您应该为此使用原型。
如果您将这些方法定义为实例属性,它们将分别为每个实例重新定义 new
。
如果将这些方法定义移至原型,代码将得到重用:
var A = function() {
};
A.prototype.m1 = function(){ console.log('hi from m1 from A'); };
A.prototype.m2 = function(){ console.log('hi from m2 from A'); };
var B = function() {
A.call(this);
};
B.prototype = Object.create(A.prototype);
B.prototype.m2 = function(){ console.log('hi from m2 from B'); };
(new B()).m2();
(new B()).m1();
之后,原型继承真的很简单:
- 实例methods/attributes覆盖它们是原型祖先
- 在原型中找到的属性会覆盖在原型的原型(等等)中找到的属性
- 所有写入都转到实例(
instance.attr
= 42 不会覆盖原型中的属性,而是会在instance
上创建一个新属性 属性)
你需要原型继承,像这样:
var A = function (){
this.init.apply(this, arguments);
};
A.prototype = Object.create(Object.prototype, {
amount: null,
init: function (amount){
this.amount = amount;
},
method1: function() {
some_asynchronous_function(this.amount, this.method2.bind(this));
},
method2: function(result) {
do_stuff(result);
};
});
var B = function (){
this.init.apply(this, arguments);
};
B.prototype = Object.create(A.prototype, {
method2: function(result) {
do_different_stuff(result);
}
});
注意:Object.create 并非在每个环境中都有第二个参数。
大部分js框架都或多或少的支持继承,选一个吧。如果你想创建自己的,那么我已经实现了一个扩展功能here,也许你可以使用一些想法。
如果您的 A class 有太多行(例如超过 50 条)或方法(超过 10 条)或它违反了 class 方法 2 的替代方法=12=]。但我想这些东西对你来说并不重要。