HTML Dog
跳至导航

面向对象代码

人类擅长分类。对象是分类行为和数据的一种方式,使大量的代码更容易设计和思考。事实上,面向对象编程在许多用于构建各种软件的语言中都可以找到,并且被认为是一种很好的编写代码的方式。

我们已经看过 JavaScript 中的对象了——它们是命名属性和方法的集合,并且可以使用对象字面量语法即时创建。


var user = {
    name: "tom",
    say: function (words) { alert(words); }
};

使用对象来保存数据的一个原因很有用,正如前面提到的,人类大脑非常擅长对事物进行分类:一艘船;一把椅子;一只驼鹿。在代码中创建对象可以帮助你思考代码的不同部分如何契合(并希望)协同工作。

在一个大型应用程序中,你可能会有大量的对象相互交互。还记得对象是属性(如 name)和方法(如 say)的组合吗?这种将数据和行为分组到一个实体中的方式称为封装

在使用对象构建应用程序时,一个强大的工具叫做继承。这是指一个对象继承另一个对象的属性和方法。一个对象可以修改它继承的属性和方法,并且还可以添加额外的属性和方法。

所以,举个例子,你可以创建一个 moose(驼鹿)对象,它继承自 mammal(哺乳动物)对象。例如,moose 可以修改 mammalfurriness(毛发程度)属性。然后你可以创建一个 pangolin(穿山甲)对象,它也继承自哺乳动物。但是,当然,穿山甲不是毛茸茸的,它们可能有不同的 scaliness(鳞片程度)属性。

对象如何继承?

JavaScript 使用原型继承。这意味着,当一个对象继承自另一个对象时,父对象被称为子对象的原型

有几点需要知道:每个对象都维护着对其原型的引用,并且每个对象都继承自全局的 object 对象。

当你请求一个对象的属性时,JavaScript 会在该对象上查找该属性。如果找不到,它会沿着链接找到对象的原型并在那里查找该属性。它会一直这样向上查找原型链,直到找到为止,或者返回 undefined

换句话说,一个对象通过维护一个指向它想要继承的另一个对象的链接来继承属性和方法。多个对象可以继承自一个单一对象,但一个单一对象不能继承自多个其他对象,尽管它可以继承自一个继承自另一个对象。

实践中

在 JavaScript 中实现继承有多种方法。最常用的方法是构造函数模式。在这种模式下,一个叫做构造函数的函数用于创建新对象。构造函数与 new 关键字结合使用来创建对象。

这是一个构造函数的例子。注意 Person 的首字母大写——这是一个重要的约定。通常,在 JavaScript 中,如果一个名称首字母大写,它就是一个构造函数,应该与 new 关键字一起使用。


var Person = function (name) {
    this.name = name;
};

现在你可以使用 new 关键字来创建 Person 对象了。


var tom = new Person('tom');

这将生成一个如下对象


{
    name: "Tom"
}

在构造函数模式中,你通过向构造函数prototype 属性添加属性和方法来手动创建新对象将要继承的对象。就像这样


Person.prototype.say = function (words) {
    alert(this.name + ' says "' + words + '"');
};

现在,从构造函数创建的对象将拥有 say 方法。


var tom = new Person("tom");
tom.say("Hello");

// Produces an alert: tom says "Hello"

这只是个开始

继承和面向对象编程是庞大而复杂的主题,有大量的书籍都在探讨。如果你想了解更多,市面上有一些很棒的资源。

如果你想了解更多关于 new 关键字的信息,请查看 Stack Overflow 上的讨论串。想获得一篇关于构造函数更详细的文章,请查看 Constructors considered mildly confusing