JavaScript重写方法

假设你有下面的代码:

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)); } 

现在的问题是,如果有什么办法,我可以用C和A中的方法modify C的方法。在Java中,你可以使用super关键字,但是你怎么能在JavaScript中实现这样的function呢?

编辑:现在是六年来,原来的答案写了很多,改变了!

  • 如果您使用的是更新版本的JavaScript,可能使用Babel这样的工具进行编译,那么您可以使用真实的类 。
  • 如果您使用Angular或React提供的类组件构造函数,则需要查看该框架的文档。
  • 如果您使用ES5并通过原型手工制作“假”类,下面的答案仍然是正确的。

祝你好运!


JavaScript的inheritance看起来有点不同于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" 

不幸的是这有点难看,它不包含一个非常好的方法来“超”:你必须手动指定你想要调用的父类的方法。 因此,有很多工具可以使创build类更好。 试着看看Prototype.js,Backbone.js或类似的库,包括更好的在js中做OOP的语法。

由于这是Google的热门话题,我想给出一个更新的答案。

使用ES6类使得inheritance和方法更容易重写:

 '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 

super关键字指的是在inheritance类中使用的父类。 此外,父类的所有方法都绑定到子实例,所以你不必写super.method.apply(this);

至于兼容性: ES6兼容性表只显示主要玩家支持类(主要)的最新版本。 自今年1月份以来,V8浏览器已经拥有了它们(Chrome和Opera),而使用SpiderMonkey JS引擎的Firefox将在下个月正式发布Firefox 45。 在手机方面,Android仍然不支持这个function,而5个月前发布的iOS 9则有部分支持。

幸运的是, Babel是一个用于将Harmony代码重新编译为ES5代码的JS库。 ES6中的类和许多其他很酷的function可以使您的Javascript代码更具可读性和可维护性。

一次应该避免模仿古典的OO而改用原型的OO。 原型OO的一个很好的实用程序库是特征 。

而不是覆盖方法和设置inheritance链(应该总是倾向于对象组合而不是对象inheritance),那么应该将可重用的函数捆绑到特征中,并用这些特性创build对象。

现场示例

 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 : " + (ox + oy)); return o; } //C(modifyA); C(modifyB); 

在你的例子中,modify()是一个私有函数,它不能从你的A,B或C定义中的任何地方访问。 你需要声明为

 this.modify = function(){} 

C没有提及它的父母,除非你将它传递给C.如果C被设置为从A或Binheritance,它将inheritance它的公共方法(而不是像你定义的modify()那样的私有函数)。 一旦Cinheritance了父类的方法,就可以覆盖inheritance的方法。

如果你想覆盖modify()你必须先inheritanceAB ,那么最后调用的方法modify()会在全局上下文中被调用。

也许你正在试图做到这一点:

在这种情况下, Cinheritance了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(); 

除非你让所有的variables“公开”,即直接或通过prototype属性使它们成为Function成员。

 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( ) ; 
  • 在这里testing

你会注意到一些变化。

最重要的是,对所谓的“超类”构造函数的调用现在隐含在这一行中:

 <name>.prototype = new C ; 

AB现在都有可单独修改的成员xy ,如果我们写成... = C不会如此。

然后, xymodify都是“公共”成员,以便为它们分配不同的Function

  <name>.prototype.modify = function( ) { /* ... */ } 

将通过该名称“覆盖”原始Function

最后, modify的调用不能在Function声明中完成,因为当我们将所谓的“超类”设置为假定的“子类”的prototype属性时,隐式调用“超类” ”。

但是,这或多或less是如何在JavaScript中做这种事情的。

HTH,

FK

 function A() { var c = new C(); c.modify = function(){ cx = 123; cy = 333; } c.sum(); } function B() { var c = new C(); c.modify = function(){ cx = 999; cy = 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();