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