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)
在这个例子里我们在创建一个新的对象实例时,同时指派了继承的所有属性
,
但是注意,您需要在构造器
里将它们(继承的所有属性
)作为参数来指派,即使实例不要求它们被作为参数指派.
比如存在这样的情况,也许您在创建对象的时候已经得到了一个设置为任意值的属性,
即它已经拥有了一个默认值/初始值
,这种情况下,您依然需要同时指派继承的所有属性
,
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
属性的赋值.
它等价于下面这种非继承方式
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()
中为其指定其他参数。
所以,例如,如果您有一些相当简单的东西:
function Brick() {
this.width = 10;
this.height = 20;
}
您可以这样继承width
和height
属性(以及下面描述的其他步骤):
function BlueGlassBrick() {
Brick.call(this);
this.opacity = 0.5;
this.color = 'blue';
}
请注意,我们仅传入了this
到call()
中 - 不需要其他参数,因为我们不会继承通过参数设置(即传入参数)的父级的任何属性。
设置对象构造函数 Teacher() 的原型和构造器引用
到目前为止一切看起来都还行,但是我们遇到问题了。
我们已经定义了一个新的构造器,这个构造器默认有一个空的原型属性。我们需要让Teacher()
从Person()
的原型对象里继承方法。
我们要怎么做呢?
本例中使用了create(),更多的常见继承方法见js继承的几种常见方式
- 有趣的东西:
Person===Person.prototype.constructor
,不信你可以试试
对象成员总结
总结一下,您应该基本了解了以下三种属性或者方法:
- 那些定义在构造器函数中的、用于给予对象实例的。这些都很容易发现 - 在您自己的代码中,它们是构造函数中使用
this.x = x
类型的行;在内置的浏览器代码中,它们是可用于对象实例的成员(通常通过使用new
关键字调用构造函数来创建,例如var myInstance = new myConstructor()
)。 - 那些直接在构造函数上定义、仅在构造函数上可用的。这些通常仅在内置的浏览器对象中可用,并通过被直接链接到构造函数而不是实例来识别。 例如
[Object.keys()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
。 - 那些在构造函数原型上定义、由所有实例和对象类继承的。这些包括在构造函数的原型属性上定义的任何成员,如
myConstructor.prototype.x()
。
如果您现在觉得一团浆糊,别担心——您现在还处于学习阶段,不断练习才会慢慢熟悉这些知识。