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()
你必须先inheritanceA
或B
,那么最后调用的方法modify()
会在全局上下文中被调用。
也许你正在试图做到这一点:
在这种情况下, C
inheritance了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 ;
A
和B
现在都有可单独修改的成员x
和y
,如果我们写成... = C
不会如此。
然后, x
, y
和modify
都是“公共”成员,以便为它们分配不同的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();