JavaScript面向对象编程入门教程


尽管面向对象JavaScript与其他语言相比之下存在差异,并由此引发了一些争论,但毋庸置疑,JavaScript具有强大的面向对象编程能力

本文先从介绍面向对象编程开始,然后回顾JavaScript对象模型,最后演示JavaScript中的面向对象编程概念。

JavaScript回顾

如果你对诸如变量(variables)、类型(types)、函数(functions)、以及作用域(scope)等JavaScript概念觉得心里没底,那么你可以阅读重新介绍JavaScript中的这些主题。你还可以查阅Object.create。

构造函数(The Constructor)

当实例化时(创建对象实例的瞬间)是会调用构造函数。构造函数是类的一个方法。而在JavaScript中,会函数(function)作为作为该对象的构造函数;因此,也就无需显式定义一个构造函数方法。类中声明的每个行为在实例化时都会执行。

构造函数用于设置对象属性或调用方法为使用该对象做准备。本文稍后会介绍,通过使用一种不同的语法来添加类方法及其定义 。

在下例中,当实例化Person时,Person类的构造函数会显示一个警告框。

Function.call和Function.apply

继承(Inheritance)

继承是一种方法,用于创建作为一个或多个类专用版本的类。(JavaScript仅支持单类继承)。这个专用类通常被称为子类(child),而其他类通常被称为父类(parent)。在JavaScript中,你要完成继承,需将父类的实例赋给子类,然后将子类特化(specializing)。

提示:由于JavaScript不检测的子类的prototype.constructor(原型的构造函数),参阅Core JavaScript 1.5核心参考:Global Objects:Object:prototype属性,因此我们必须手动指定该值。

在下例中,我们定义Student类作为Person的子类。然后我们重新定义sayHello()方法,并添加sayGoodBye()方法。

复制代码 代码如下:

// 定义Person类
function Person() {}
Person.prototype.walk = function() {
    alert('I am walking!');
};
Person.prototype.sayHello = function() {
    alert('hello');
};
// 定义Student类
function Student() {
    //调用父类构造函数
    Person.call(this);
}
// 继承Person
Student.prototype = new Person(); // 修正构造函数指针,由于它指向Person
Student.prototype.constructor = Student; // 替换sayHello方法
Student.prototype.sayHello = function() {
    alert('hi, I am a student');
}
// 添加sayGoodBye方法
Student.prototype.sayGoodBye = function() {
    alert('goodBye');
}
var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye(); // 检验继承
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true


封装

在上例中,Student无须知晓Person类的walk()方法是如何实现的,但仍可使用该方法;Student类无须显式定义该方法,除非我们想改变它。这称为封装(encapsulation),这样每个类继承其父类的方法,并且只需定义它所希望改变的东西。

抽象

抽象是一种机制(mechanism),允许对处理中的问题的当前部分进行建模。这可以通过继承(特化)或组合(composition)来实现。JavaScript通过继承实现特化(specialization),通过让类实例成为其他对象的属性值实现组合。
JavaScript的Function类继承自Object类(这说明模型的特化),并且Function.prototype属性是Object的实例(这说明了组合)。

复制代码 代码如下:
var foo = function() {};
alert('foo is a Function: ' + (foo instanceof Function));
alert('foo.prototype is an Object: ' + (foo.prototype instanceof Object));

多态

就像所有的方法和属性被定义在原型属性内部一样,不同的类可以定义具有相同名称的方法;方法的作用域限于定义它们的类之内。这仅当两个类之间没有父子关系(当一个类没有从继承链中的其他类继承时)时才为真。

提示

本文中所提出的面向对象编程实现技术不仅适用于JavaScript,因为就如何进行面向对象编程而言,这是非常灵活的。
同样,这里展示的技术既没有使用任何语言技巧(language hacks),也没有模仿其他语言的对象理论实现。
在JavaScript中,还有其他更高级的面向对象编程的技术,但是那些内容已超出了这篇介绍性文章的范围。


« 
» 

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3