JavaScript中的继承——笔记

学习文档:MDN web docs —— JavaScript中的继承 

 

 

目标:理解在JavaScript中如何实现继承。(其实看完了也不一定能理解,没关系,写篇笔记表示我学过)

 

1. 编写一个Person()构造器

function Person (first, last, age, gender, interests) {
    this.name = {
        first,
        last
    };

    this.age = age;
    this.gender = gender;
    this.interests = interests;
}

实例方法可定义在Person构造器的原型上,比如:

Person.prototype.greeting = function () {
    alert('Hi! I\'m ' + this.name.first + '.');
};

 

2. 现在,我们创建一个Teacher类

让它继承Person的所有成员,并且添加一个新的属性,subject——教师教授的学科,还要一个被更新的greeting方法。

 

定义Teacher()构造器函数

function Teacher (first, last, age, gender, interests, subject) {
    Person.call(this, first, last, age, gender, interests);

    this.subject = subject;
}

 

设置Teacher()的原型和构造器引用

Teacher.prototype = Object.create(Person.prototype);

用create函数来创建一个和Person.prototype一样的新的原型属性值(这个属性指向一个包括属性和方法的对象),这意味着Teacher.prototype现在会继承Person.prototype的所有属性和方法。但是这里有个问题,Teacher.prototype.constructor的值是Person(),这会让人迷惑。可以通过以下代码修改它的值。

Teacher.prototype.constructor = Teacher;

这样就对了。

 

注:

每一个函数对象(Function)都有一个prototype属性,并且只有函数对象有prototype属性,因为prototype本身就是定义在Function对象下的属性。

当我们输入以下代码来构造对象时

var person1 = new Person(...)

JavaScript实际上参考的是Person.prototype指向的对象来生成person1.

Person()函数是Person.prototype的构造函数,也就是说:

Person === Person.prototype.constructor
// true

 

在定义新的构造函数Teacher时,我们通过Function.call来调用父类的构造函数,但是无法自动指定Teacher.prototype的值。这样Teacher.prototype就只能包含在构造函数里构造的属性,而没有方法。因此我们利用Object.create()方法将Person.prototype作为Teacher.prototype的原型对象,并且改变其构造器指向,使之与Teacher关联

 

任何你想要被继承的方法都应该定义在构造函数的prototype对象里,并且永远使用父类的prototype来创造子类的prototype,这样才不会打乱继承结构。

 

 

向Teacher()添加一个新的greeting()函数

最简单的方法是在Teacher的原型上定义它

Teacher.prototype.greeting = function () {
    var prefix;
    if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
        prefix = 'Mr.'
    } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
        prefix = 'Mrs.';
    } else {
        prefix = 'Mx.'
    }

    alert('Hello, My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
}

 

 

3.创建一个Teacher构造函数的实例

var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');

试试这位老师实例的属性和方法

teacher1.name.first;
teacher1.interests[0];
teacher1.subject;
teacher1.greeting();

 

 

4.对象成员总结

你应该基本了解以下三种属性或者方法:

  1. 那些定义在构造器函数中的、用于给予对象实例的。例如构造函数中使用this.x = x这种。它们是可用于对象实例的成员。
  2. 那些直接在构造函数上定义、仅在构造函数上可用。
  3. 那些在构造函数原型上定义、由所有实例和对象类继承的。这些包括在构造函数的原型属性上定义的任何成员。例如myConstructor.prototype.x()

 

5.何时在JavaScript中使用继承?

  • 原型和继承代表了JavaScript这门语言里最复杂的部分。
  • JavaScript的强大和灵活性正是来自于它的对象体系和继承方式,这很值得花时间去好好理解下它是如何工作的
  • 通常,在小型项目中或者你刚开始学习js的时候,你可能不太需要用到继承。随着代码量的增大,你会发现它的必要性。
  • 如果你开始创建一系列拥有相似特性的对象时,那么创建一个包含所有共有功能的通用对象,然后再更特殊的对象类型中继承这些特性,将会变得更加方便有用。
  • 在不同对象之间功能的共享通常被叫做委托
  • 总之,对象是另一种形式的代码重用。如果你发现自己创建了一堆相关的变量和函数,还想一起追踪它们并将其灵活打包时,对象是个不错的注意。

 

posted on 2019-07-16 17:36  独自去流浪  阅读(173)  评论(0编辑  收藏  举报