javascript-js的继承

I keep asking myself these three questions… What do you have? What do you want? What will you give up?
Jack Ma

本系列关注前端部分,根据学习路线图达到学习Vue.js的目的

developer路线图developer-roadmap/translations/chinese at master · kamranahmedse/developer-roadmap

本系列笔记的源代码GitHub项目地址:learning-area/front-end-learning at master · YJ2CS/learning-area

快速跳转

目录:前端学习路线-目录

从继承链的原型上进行继承(原型式继承 —— prototypal inheritance)

在这个例子里我们在创建一个新的对象实例时,同时指派了继承的所有属性

但是注意,您需要在构造器里将它们(继承的所有属性)作为参数来指派,即使实例不要求它们被作为参数指派.

比如存在这样的情况,也许您在创建对象的时候已经得到了一个设置为任意值的属性,

即它已经拥有了一个默认值/初始值,这种情况下,您依然需要同时指派继承的所有属性

1
2
3
4
5
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);

this.subject = subject;
}

这里Person.call()中的this,本质上是指向Teacher()函数的this,

即是一个这样的过程:

一个实参this向形参this传递,并最终完成对实参this(它指向Teacher)的赋值.

它实际上是将Teacher()中的this传递给Person.call(),以完成对 Teacher属性的赋值.

它等价于下面这种非继承方式

1
2
3
4
5
6
7
8
9
10
function Teacher(first, last, age, gender, interests, subject) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.subject = subject;
}

但是这只是重新定义了一遍属性,并不是将他们从Person()中继承过来的,所以这违背了我们的初衷。这样写也会需要更长的代码。

从无参构造函数继承

请注意,如果您继承的构造函数不从传入的参数中获取其属性值,则不需要在call()中为其指定其他参数。

所以,例如,如果您有一些相当简单的东西:

1
2
3
4
function Brick() {
this.width = 10;
this.height = 20;
}

您可以这样继承widthheight属性(以及下面描述的其他步骤):

1
2
3
4
5
6
function BlueGlassBrick() {
Brick.call(this);

this.opacity = 0.5;
this.color = 'blue';
}

请注意,我们仅传入了thiscall()中 - 不需要其他参数,因为我们不会继承通过参数设置(即传入参数)的父级的任何属性。

设置对象构造函数 Teacher() 的原型和构造器引用

到目前为止一切看起来都还行,但是我们遇到问题了。

我们已经定义了一个新的构造器,这个构造器默认有一个空的原型属性。我们需要让Teacher()Person()的原型对象里继承方法。

我们要怎么做呢?

本例中使用了create(),更多的常见继承方法见js继承的几种常见方式

  • 有趣的东西:Person===Person.prototype.constructor,不信你可以试试

对象成员总结

总结一下,您应该基本了解了以下三种属性或者方法:

  1. 那些定义在构造器函数中的、用于给予对象实例的。这些都很容易发现 - 在您自己的代码中,它们是构造函数中使用this.x = x类型的行;在内置的浏览器代码中,它们是可用于对象实例的成员(通常通过使用new关键字调用构造函数来创建,例如var myInstance = new myConstructor())。
  2. 那些直接在构造函数上定义、仅在构造函数上可用的。这些通常仅在内置的浏览器对象中可用,并通过被直接链接到构造函数而不是实例来识别。 例如[Object.keys()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
  3. 那些在构造函数原型上定义、由所有实例和对象类继承的。这些包括在构造函数的原型属性上定义的任何成员,如myConstructor.prototype.x()

如果您现在觉得一团浆糊,别担心——您现在还处于学习阶段,不断练习才会慢慢熟悉这些知识。