前言
Javascript是我最喜欢的几种语言之一,从暑假后半段一直到开学一直在看《Javascript高级程序设计》,我觉得这本书很好,讲得很全面,但对于js中的原型链自己还是有必要花点时间好好理一理,于是就写下此篇文章。
基础知识
先来讲讲js中创建对象的几种方法。
1 | //第一种:字面量 |
让我们看看结果:
3种创建方法返回的结果是不一样的。这就和这篇文章要讲的有关系。
原型&&原型链
先上两张《js高级程序设计》中关于原型链的图片
这两张图对于萌新甚至是某些老手都没理解清楚。
我自己做了一张流程图,下面我们就来细说图中的名词。
让我们从实例出发:
1 | var F = function(name){this.name = name;} |
- 所谓的实例就是生成出来的对象,例如上面的例子中o3就是实例
- F就是构造函数,用来提供创建对象的方法
- 实例中的__proto__指向原型对象
- 实例的构造函数的prototype也是指向的原型对象
- 原型对象的construor指向的是构造函数
那什么是原型链呢?
简单地说,就是由原型所组成的链,一个对象的__proto__就是它的原型,而这个原型也是一个对象,所以他也有__proto__属性,指向它的上一个原型,一直通过__proto__向上查找,直到Object的时候,这条原型链就到头了。
说了这么多,原型链到底有啥用?
当我们通过构造函数创建了许多实例,如果某些对象要增加方法,一个个去实例中添加就很繁琐,这时我们可以将方法添加到原型中,使这个原型的所有实例都有这个方法。举个代码例子:
1 | var F = function(name){this.name = name;} |
原型链的另一个作用就是继承,再举个简单的小例子:
1 | var Father = function(name){this.name = name;}; |
这里可以很清楚,b中并没有say这个方法,而是从father那边继承过来的,我们可以看看Son.prototype
可以看到原型链一直到Object。
回到最初创建对象的方法。
第一种就直接使用Object类来创建实例,所以__proto__直接指向了Object;第二种方法使用了构造函数,可以看到o3的__proto__指向了__函数构造出来的对象(原型对象)__,而这个对象的__proto__s指向的是Object;最后第三种方法使用了Object.create。MDN的文档中给出:Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
所以o4._proto__指向的是它的父对象(允许我这么叫它),而o4._proto.__proto__指向的才是Object。
这也就是为什么三种方式在console里面返回的结果不同。至于使用构造函数创建的o3在console里为什么会这么显示,让人觉得o3.__proto__指向Object就不得而知了。
总结
对于js,原型链一直是它的难点和重点,这次通过简单的复习和梳理再次学习了一下。
写下这篇文章也算是对JavaScript的一种喜爱和敬畏吧,对于原型链也只是了解了皮毛,希望今后对js的学习可以更加深入。
如有错误或者讲的不当的地方请与我联系。
参考
《JavaScript高级程序设计》
https://www.cnblogs.com/chengzp/p/prototype.html