通天战队|「翻译」JavaScript的可视化学习之五:原型继承

我之所以能成功 , 是因为我站在巨人的肩膀上 。- 隐形富豪Prototypal Inheritance
通天战队|「翻译」JavaScript的可视化学习之五:原型继承原型继承的概览图
请注意上面这张图 , 原型继承的那些事 , 将在这个图上缓缓展开 。
有没有想过为什么我们可以在字符串、数组或对象上使用内置方法 , 如.length、.split()、.join()?我们从来没有明确指定过 , 它们是从哪里来的?不要说“这是JavaScript布拉布拉 , 没人知道 , 它有魔法” , 实际上是因为一种叫做原型继承的东西 。 它非常棒 , 而且你使用它的次数比你以为的还要多!
我们经常要创建许多相同类型的对象 。 假设我们有一个网站 , 人们可以在上面浏览狗狗!
对于每一只狗 , 我们都需要一个对象来表示它!我不需要每次都编写一个新的对象 , 而是使用一个构造函数(我知道您在想什么 , 稍后我将介绍ES6类!) , 从中我们可以使用“new”关键字创建“Dog”对象(不过 , 这篇文章并不是要解释构造函数 , 所以我不会过多地讨论这个问题) 。
每只狗都有名字、品种、颜色和吠叫的功能!
function Dog(name, breed, color) {this.name = namethis.breed = namethis.color = namethis.bark = function() {return 'Woof!'}}当我们创建“Dog”构造函数时 , 它并不是我们创建的唯一对象 。 我们还自动创建了另一个对象 , 称为“prototype”!默认情况下 , 此对象包含一个“constructor”属性 , 它只是对原始构造函数的简单引用 , 在本例中是“Dog” 。
通天战队|「翻译」JavaScript的可视化学习之五:原型继承1、创建构造函数时 , 同时创建了prototype对象 。
“Dog”构造函数上的“prototype”属性是不可枚举的 , 这意味着当我们试图获取对象属性时 , 它不会出现 。 但它就在那里!
好吧所以 。。。 为什么我们有这个属性对象?首先 , 让我们创造一些我们想展示的狗狗 。 为了简单起见 , 我称它们为“dog1”和“dog2” 。 小狗1是黛西 , 一只可爱的黑色拉布拉多犬!小狗2是杰克 , 勇敢的白种人杰克·罗素 。
const dog1 = new Dog("Daisy","Labrador","black")const dog2 = new Dog("Jack","Jack Russell","white")让我们将“dog1”输出到控制台 , 并展开它的属性!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承我们可以看到添加的属性 , 如“name”、“breed”、“color”和“bark” 。。。 但是哇哦“__proto__”是什么东西啊!它是不可枚举的 , 这意味着当我们试图获取对象的属性时 , 它通常不会出现 。 让我们展开它!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承哇哦它看起来很像“Dog.prototype”对象!你猜怎么着 , “__proto__”指向“Dog.prototype”对象 。 这就是原型继承的目的:构造函数的每个实例都可以访问构造函数的原型!
通天战队|「翻译」JavaScript的可视化学习之五:原型继承3、每个实例包含一个__proto__属性指向构造函数的原型 。
为什么这很酷?有时我们拥有所有实例共享的属性 。 例如本例中的“bark”函数:它对每个实例都是完全相同的 , 为什么每次创建一个新的“dog”时都创建一个新函数 , 每次都消耗内存?相反 , 我们可以将其添加到“Dog.prototype”对象!


推荐阅读