继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义,分别封装中国人和日本人的行为特征来理解编程中继承的含义,代码如下:
<script>
// 封装中国人的行为特征
function Chinese() {
// 中国人的特征
this.arms = 2;
this.legs = 2;
this.eyes = 2;
this.skin = 'yellow';
this.language = '中文';
// 中国人的行为
this.walk = function () {}
this.sing = function () {}
this.sleep = function () {}
}
// 封装日本人的行为特征
function Japanese() {
// 日本人的特征
this.arms = 2;
this.legs = 2;
this.eyes = 2;
this.skin = 'yellow';
this.language = '日文';
// 日本人的行为
this.walk = function () {}
this.sing = function () {}
this.sleep = function () {}
}
</script>
其实我们都知道无论是中国人、日本人还是其它民族,人们的大部分特征是一致的,然而体现在代码中时人的相同的行为特征被重复编写了多次,代码显得十分冗余,我们可以将重复的代码抽离出来:
原型继承
通过手动修改构造函数的原型对象,来实现继承
function Father() {
this.money = 1000
this.diaotoufa = true
}
let f = new Father()
function Son() {
this.money = 50
}
// 手动修改Son的原型对象(自己写了一个对象的继承关系;)
Son.prototype = f
let s = new Son()
console.log(s.momey) // 50 // 优先调用自己的属性
console.log(s.diaotoufa) // true 对象自己没有这个属性,则使用继承下来的属性
原型链
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链,如上图所示。
在 JavaScript 对象中包括了一个非标准备的属性 __proto__
它指向了构造函数的原型对象,通过它可以清楚的查看原型对象的链状结构。
1.3 写在最后
面向对象(OOP)是编程时的一种指导思想,需要通过不断的实践才能体会面向对象编程的优势,在 JavaScript 中面向对象编程的实现是以构造函数和原型对象为核心的,因此掌握构造函数和原型对象的语法是灵活运用面向对象的基础。
面向对象多态的特性在 JavaScript 中应用场景相对较少,本次课中暂不讲解。