JavaScript 覆盖方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6885404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript override methods
提问by Daniel Nastase
Let's say you have the below code:
假设您有以下代码:
function A() {
function modify() {
x = 300;
y = 400;
}
var c = new C();
}
function B() {
function modify(){
x = 3000;
y = 4000;
}
var c = new C();
}
C = function () {
var x = 10;
var y = 20;
function modify() {
x = 30;
y = 40;
};
modify();
alert("The sum is: " + (x+y));
}
Now the question is, if there is any way in which I can override the method modify
from C
with the methods that are in A
and B
. In Java you would use the super
-keyword, but how can you achieve something like this in JavaScript?
现在的问题是,如果有任何方式,我可以覆盖的方法modify
,从C
与在方法A
和B
。在 Java 中,您会使用super
-keyword,但是如何在 JavaScript 中实现这样的功能呢?
回答by Adam
Edit: It's now six years since the original answer was written and a lot has changed!
编辑:距离最初的答案已经写了六年,而且已经发生了很多变化!
- If you're using a newer version of JavaScript, possibly compiled with a tool like Babel, you can use real classes.
- If you're using the class-like component constructors provided by Angularor React, you'll want to look in the docs for that framework.
- If you're using ES5 and making "fake" classes by hand using prototypes, the answer below is still as right as it ever was.
- 如果您使用的是较新版本的 JavaScript,可能是用Babel 之类的工具编译的,则可以使用真正的类。
- 如果您正在使用Angular或React提供的类组件构造函数,您需要查看该框架的文档。
- 如果您正在使用 ES5 并使用原型手工制作“假”类,那么下面的答案仍然和以前一样正确。
Good luck!
祝你好运!
JavaScript inheritance looks a bit different from Java. Here is how the native JavaScript object system looks:
JavaScript 继承看起来与 Java 有点不同。以下是原生 JavaScript 对象系统的外观:
// Create a class
function Vehicle(color){
this.color = color;
}
// Add an instance method
Vehicle.prototype.go = function(){
return "Underway in " + this.color;
}
// Add a second class
function Car(color){
this.color = color;
}
// And declare it is a subclass of the first
Car.prototype = new Vehicle();
// Override the instance method
Car.prototype.go = function(){
return Vehicle.prototype.go.call(this) + " car"
}
// Create some instances and see the overridden behavior.
var v = new Vehicle("blue");
v.go() // "Underway in blue"
var c = new Car("red");
c.go() // "Underway in red car"
Unfortunately this is a bit ugly and it does not include a very nice way to "super": you have to manually specify which parent classes' method you want to call. As a result, there are a variety of tools to make creating classes nicer. Try looking at Prototype.js, Backbone.js, or a similar library that includes a nicer syntax for doing OOP in js.
不幸的是,这有点难看,它没有包含一个很好的“超级”方法:您必须手动指定要调用的父类的方法。因此,有多种工具可以更好地创建类。尝试查看 Prototype.js、Backbone.js 或包含在 js 中执行 OOP 的更好语法的类似库。
回答by Yotam Ofek
Since this is a top hit on Google, I'd like to give an updated answer.
由于这是谷歌上的热门话题,我想给出一个更新的答案。
Using ES6 classesmakes inheritance and method overriding a lot easier:
使用ES6 类使继承和方法覆盖更容易:
'use strict';
class A {
speak() {
console.log("I'm A");
}
}
class B extends A {
speak() {
super.speak();
console.log("I'm B");
}
}
var a = new A();
a.speak();
// Output:
// I'm A
var b = new B();
b.speak();
// Output:
// I'm A
// I'm B
The super
keywordrefers to the parent class when used in the inheriting class. Also, all methods on the parent class are bound to the instance of the child, so you don't have to write super.method.apply(this);
.
该super
关键字在继承类使用时指的是父类。此外,父类上的所有方法都绑定到子类的实例,因此您不必编写super.method.apply(this);
.
As for compatibility: the ES6 compatibility tableshows only the most recent versions of the major players support classes (mostly). V8 browsers have had them since January of this year (Chrome and Opera), and Firefox, using the SpiderMonkey JS engine, will see classes next month with their official Firefox 45 release. On the mobile side, Android still does not support this feature, while iOS 9, release five months ago, has partial support.
至于兼容性:ES6 兼容性表仅显示了主要播放器支持类(大部分)的最新版本。V8 浏览器自今年 1 月(Chrome 和 Opera)开始使用它们,而使用 SpiderMonkey JS 引擎的 Firefox 将在下个月发布正式版 Firefox 45。在移动端,Android 仍然不支持此功能,而五个月前发布的 iOS 9 部分支持。
Fortunately, there is Babel, a JS library for re-compiling Harmony code into ES5 code. Classes, and a lot of other cool features in ES6 can make your Javascript code a lot more readable and maintainable.
幸运的是,有Babel,一个用于将 Harmony 代码重新编译为 ES5 代码的 JS 库。ES6 中的类和许多其他很酷的功能可以使您的 Javascript 代码更具可读性和可维护性。
回答by Raynos
Once should avoid emulating classical OO and use prototypical OO instead. A nice utility library for prototypical OO is traits.
曾经应该避免模仿经典的面向对象,而是使用原型面向对象。原型 OO 的一个很好的实用程序库是traits。
Rather then overwriting methods and setting up inheritance chains (one should always favour object composition over object inheritance) you should be bundling re-usable functions into traits and creating objects with those.
而不是覆盖方法和设置继承链(一个人应该总是倾向于对象组合而不是对象继承),你应该将可重用的函数捆绑到特征中并用这些函数创建对象。
var modifyA = {
modify: function() {
this.x = 300;
this.y = 400;
}
};
var modifyB = {
modify: function() {
this.x = 3000;
this.y = 4000;
}
};
C = function(trait) {
var o = Object.create(Object.prototype, Trait(trait));
o.modify();
console.log("sum : " + (o.x + o.y));
return o;
}
//C(modifyA);
C(modifyB);
回答by Alex Heyd
modify() in your example is a private function, that won't be accessible from anywhere but within your A, B or C definition. You would need to declare it as
您的示例中的 modify() 是一个私有函数,除了在您的 A、B 或 C 定义中,它不能从任何地方访问。您需要将其声明为
this.modify = function(){}
C has no reference to its parents, unless you pass it to C. If C is set up to inherit from A or B, it will inherit its public methods (not its private functions like you have modify() defined). Once C inherits methods from its parent, you can override the inherited methods.
C 没有对其父项的引用,除非您将其传递给 C。如果 C 设置为从 A 或 B 继承,它将继承其公共方法(而不是像您定义的 modify() 那样的私有函数)。一旦 C 从其父级继承方法,您就可以覆盖继承的方法。
回答by lovesh
the method modify()
that you called in the last is called in global context
if you want to override modify()
you first have to inherit A
or B
.
该方法modify()
,如果你想越过你在过去被称为被称为在全球范围内modify()
,你首先必须继承A
或B
。
Maybe you're trying to do this:
也许你正在尝试这样做:
In this case C
inherits A
在这种情况下C
继承A
function A() {
this.modify = function() {
alert("in A");
}
}
function B() {
this.modify = function() {
alert("in B");
}
}
C = function() {
this.modify = function() {
alert("in C");
};
C.prototype.modify(); // you can call this method where you need to call modify of the parent class
}
C.prototype = new A();
回答by FK82
Not unless you make all variables "public", i.e. make them members of the Function
either directly or through the prototype
property.
除非您将所有变量设为“公共”,即Function
直接或通过prototype
属性使它们成为 的成员。
var C = function( ) {
this.x = 10 , this.y = 20 ;
this.modify = function( ) {
this.x = 30 , this.y = 40 ;
console.log("(!) C >> " + (this.x + this.y) ) ;
} ;
} ;
var A = function( ) {
this.modify = function( ) {
this.x = 300 , this.y = 400 ;
console.log("(!) A >> " + (this.x + this.y) ) ;
} ;
} ;
A.prototype = new C ;
var B = function( ) {
this.modify = function( ) {
this.x = 3000 , this.y = 4000 ;
console.log("(!) B >> " + (this.x + this.y) ) ;
} ;
} ;
new C( ).modify( ) ;
new A( ).modify( ) ;
new B( ).modify( ) ;
You will notice a few changes.
您会注意到一些变化。
Most importantly the call to the supposed "super-classes" constructor is now implicit within this line:
最重要的是,对假定的“超类”构造函数的调用现在隐含在这一行中:
<name>.prototype = new C ;
Both A
and B
will now have individually modifiablemembers x
and y
which would not be the case if we would have written ... = C
instead.
无论A
和B
现在有个别修改成员x
和y
这不会是我们是否有书面的情况... = C
相反。
Then, x
, y
and modify
are all "public" members so that assigning a different Function
to them
然后,x
,y
和modify
都是“公共”成员,以便Function
为他们分配不同的
<name>.prototype.modify = function( ) { /* ... */ }
will "override" the original Function
by that name.
将Function
通过该名称“覆盖”原件。
Lastly, the call to modify
cannot be done in the Function
declaration because the implicit call to the "super-class" would then be executed again when we set the supposed "super-class" to the prototype
property of the supposed "sub-classes".
最后,modify
不能在Function
声明中调用 ,因为当我们将假定的“超类”设置为假定的“子类”的prototype
属性时,将再次执行对“超类”的隐式调用。
But well, this is more or less how you would do this kind of thing in JavaScript.
但是,这或多或少是你在 JavaScript 中做这种事情的方式。
HTH,
哈,
FK
FK
回答by nghien_net 89
function A() {
var c = new C();
c.modify = function(){
c.x = 123;
c.y = 333;
}
c.sum();
}
function B() {
var c = new C();
c.modify = function(){
c.x = 999;
c.y = 333;
}
c.sum();
}
C = function () {
this.x = 10;
this.y = 20;
this.modify = function() {
this.x = 30;
this.y = 40;
};
this.sum = function(){
this.modify();
console.log("The sum is: " + (this.x+this.y));
}
}
A();
B();