这个章节要来複习第六章所学到的观念
那么动物的原型因为是比较高的阶层,所以我们又可以有别的动物来继承动物的原型,在上一张的最后则是由猫的原型来继承
猫的原型 继承了 动物的原型,也有自己的方法。并且也可以透过猫的原型产生猫的实体。猫的实体 也是继承了 猫的原型。好~说到这里感觉很像绕口令齁~ 我们用下面这张表来看一下这些东西的互相关係
那么为了让画面简洁一点呢,这边没有显示出猫的实体以及猫的原型!
另外呢画面上有绿色字体显示的,Dog、Animal、Object、Function,这些呢都是属于建构函式
首先呢我们先专注在最左上方的比比(狗的实体),如果我们使用console.log来看比比的话,就会显示出这样的结果。
那么比比的内容呢,有包含了 name、family、color以及这个章节介绍的重点 __proto__
。
这个 __proto__
会指向狗的原型,而狗的原型就是透过狗的建构函式而来,所以狗的原型的 constructor 会指向 狗的建构函式。
同时狗的原型的 __proto__
也可以向上寻找,找到动物的原型。
每一个原型都会有一个 constructor 去指向这个建构函式。
所以动物的原型的 constructor 就会去指向动物的建构函式
然后动物的 __proto__
也可以向上寻找,找到物件的原型。
然后物件的原型的 constructor 也会连结到 物件的建构函式。
如果物件的建构函式的 __proto__
继续向上寻找,最后会找到 null 的结果。
了解到这里,其实你已经掌握了绝大部分的概念,那么我们再多说一些观念吧!
首先先把刚刚的部分调淡一些些。
刚刚的 Dog、Animal、Object 都可以利用 Dog、Animal、Object.prototype 来产生原型或是将方法挂载在这些建构函式的原型链上。
那么为什么,我们可以使用 prototype 这个方法呢?
那是因为 Dog、Animal、Object 的 __proto__
都是继承于 Function 这个建构函式的 prototype。
最后我们再来看一下 函式, Function 的原型。
Function 的原型的 __proto__
继续向上寻找,一样会找到物件的原型。
Function 的原型的 constructor 会指向 Function 的建构函式。
Function 的建构函式的 __proto__
则会指向回 Function 的原型。
接着就来用程式码来验证一下吧!
function Animal (family) { this.kingdom = '动物界'; this.family = family || '人科';}Animal.prototype.move = function () { console.log(this.name + ' 移动');};function Dog (name, color, size) { Animal.call(this, '犬科'); this.name = name; this.color = color || '白色'; this.size = size || '小';}Dog.prototype = Object.create(Animal.prototype);Dog.prototype.constructor = Dog;Dog.prototype.bark = function () { console.log(this.name + '吠叫');}var Bibi = new Dog('比比', '棕色', '小');console.log(Bibi.__proto__ === Dog.prototype);
透过这样的结果我们可以知道 这个 proto
会指向狗的原型,而狗的原型就是透过狗的建构函式而来,这个观念是对的。
那我们继续再加上~
console.log(Bibi.__proto__.__proto__ === Animal.prototype);
所以往上找两层也就是 狗实体 >> 狗原型 >> 动物原型,而答案也是 true。
再来验证建构器 constructor 的观念
那我们继续再加上~
console.log(Bibi.__proto__.__proto__.constructor === Animal);
那么 动物原型 的 建构器 很明显就应该要是动物的建构函式,答案一样也是 true,代表的确动物的原型的 constructor 是指向动物的建构函式。
再来验证原型链的最上层会是 null
那我们继续再加上~
console.log(Bibi.__proto__.__proto__.__proto__.__proto__ === null);
那么验证的结果也是 true。
验证 所有的建构函式都是继承 Function 的原型
那我们继续再加上~
console.log(Dog.__proto__ === Function.prototype);console.log(Animal.__proto__ === Function.prototype);console.log(Object.__proto__ === Function.prototype);
验证 Function 的 __proto__
是否指向 Function 的原型
那我们继续再加上~
console.log(Function.__proto__ === Function.prototype);
同时,Function 的原型再向上寻找就会找到物件的原型喔!
那我们继续再加上~
console.log(Function.__proto__.__proto__ === Object.prototype);
所以这个观念也被验证!
以上就是原型链以及继承的关係,也可以参考 MDN 继承与原型链的文章
来更深入的学习喔!
没问题的话就可以来做做后面的习题喔!