很多C#或C++开发人员习惯使用继承来开发项目,所以当他们想学习JavaScript语言时,第一个问题一般是:“我怎么在JavaScript中使用继承?”。
实际上JavaScript使用了一种不同于C#或C++的方法来创建面向对象语言。它是基于prototype的语言。原型概念表明行为是可以通过clone已经存在的对象来作为原型复用的。在JavaScript中每个对象都有原型,它定义了一系列对象可以使用的方法和成员。没有class,只有对象。每一个对象可以作为另一个对象的原型。
这个概念是非常灵活的,我们可以用它来模拟OOP继承。
实现继承
让我们想象我们使用JavaScript创建这个层次机构:
首先我们可以简单地创建ClassA。因为没有明确的类,我们只需创建一个函数定义一组行为:
var ClassA = function(){ this.name = "class A"; }
使用new 关键字来实例化这个“类”:
var a = new ClassA(); ClassA.prototype.print = function(){ console.log(this.name); }
然后使用对象来使用它:
a.print()
很简单,对吧?
完整的样式只用了8行代码:
var ClassA = function() { this.name = "class A"; } ClassA.prototype.print = function() { console.log(this.name); } var a = new ClassA(); a.print();
现在让我们来创建类之间的“继承”。这个工具只做一件简单的事:克隆原型:
var inheritsFrom = function(child, parent) { child.prototype = Object.create(parent,prototype); };
奇迹发生了!通过clone原型,我们将所有成员和函数传给新类。
所以如果我们想添加第一个类的子类,只需要使用这段代码:
var ClassB = function() { this.name = "class B"; this.surname = "I‘m the child"; } inheritsFrom(ClassB, ClassA);
所以ClassB继承了ClassA的print函数,所以下面代码是有效的:
var b = new ClassB(); b.print();
所以产生以下输出:
class B
我们甚至可以覆盖ClassB的print函数:
ClassB.prototype.print = function(){ ClassA.prototype.print.call(this); console.log(this.surname); }
在这种情况下,输出是这样的:
class B I’m the child
这里的技巧是调用ClassA.prototype来获取print函数。由于call函数我们可以对当前对象(this)调用基本函数。
创建ClassC是显而易见的:
var ClassC = function () { this.name = "class C"; this.surname = "I‘m the grandchild"; } inheritsFrom(ClassC, ClassB); ClassC.prototype.foo = function() { // Do some funky stuff here... } ClassC.prototype.print = function () { ClassB.prototype.print.call(this); console.log("Sounds like this is working!"); } var c = new ClassC(); c.print();
输出:
class C I’m the grandchild Sounds like this is working!
总结
最后,我想说明JavaScript不是C#或C++。它有自己的哲学。如果你说C++或C#程序员,并且你真的很想了解JavaScript所有精华,我给你最好的提示:不要试图将你的语言复制到JavaScript。没有最好的语言或最差的语言。只是不同的哲学!
链接: http://www.sitepoint.com/simple-inheritance-javascript/