很多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/