原型是什么?
JavaScript是一门基于原型的语言,在JavaScript中没有类的定义,而是使用原型和原型链来实现模拟实现类和类的继承的关系(ES6的类也只是语法糖)。什么是原型呢?
这个网红布丁小兔子,很可爱吧,是怎么做出来的呢?
首先调好布丁原料,然后拿出模具,将原料倒入,等待成型之后,轻轻的取出来,最后将成型的兔子的耳朵和鼻子图上红色,眼睛涂上黑色,就大功告成啦。这个时候就可以拿出手机拍照发朋友圈。。。跑偏了。。。
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
以上摘自MDN上对原型的一句描述。我们回头看我们只做兔子布丁的这个过程,我们以模具(原型对象)
为模板,成型(继承了原型的形状这个属性)
之后取出,给兔子的耳朵和鼻子上色(实现了自己的方法和属性)
。
在JS中,对象都会包含一个属性__proto__指向了它的原型。所有会有({}).__proto__ === Object.prototype
,同时也可以通过({}).__proto__.constructor
找到Object
。
读了上面这段话,又引出了一个问题,prototype
又是什么东西?
在javascript中,函数可以有属性。 每个函数都有一个特殊的属性叫作原型(prototype)。
mdn中有这样一段话,是的,prototype
是在生成函数时,自动添加上去的一个属性。
什么是原型链?
在传统的 OOP 中,首先定义“类”,此后创建对象实例时,类中定义的所有属性和方法都被复制到实例中。在 JavaScript 中并不如此复制——而是在对象实例和它的构造器之间建立一个链接(它是__proto__属性,是从构造函数的prototype属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法。
在JS中没有类的概念,那么是怎么实现类和继承的呢?
从上面的图中可以看到一条链式关系 s.__proto__.__proto__ === Object.prototype
,JS正是通过__proto__
和prototype
的这种依赖关系实现了原型链和继承。可以把这种链式关系想象成是长城,每个烽火台就是从前面的烽火台继承得到的实例,在当前烽火台没有找到想要的属性时,就会顺着道路(原型链)
去到前一个烽火台找,直到到达终点(Object.prototype)
或者是找到为止。
总结一下
- 每个对象上都有一个
__proto__
的属性指向它对应的原型 - 每个函数在生成的时候会添加
prototype
属性 - 原型链就是通过
__proto__
和prototype
的合作实现的 obj.__proto__ === Constructor.prototype
obj.__proto__.constructor === Construtor
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。