美文网首页
2018-09-13

2018-09-13

作者: wantSuper | 来源:发表于2018-09-13 15:51 被阅读0次

    prototype

    prototype属性是每一个函数都具有的属性,但它不是一个对象都具有的属性。比如:function  Foo(){};      var foo =new Foo();其中Foo中有prototype属性,而foo没有。但是foo中的隐含的__proto__属性指向Foo.prototype。即,foo.__proto__ === Foo.prototype.

    为什么会存在prototype属性?

    Javascript里面所有的数据类型都是对象,为了使JavaScript实现面向对象的思想,就必须要能够实现‘继承’使所有的对象连接起来。而如何实现继承呢?JavaScript采用了类似C++,java的方式,通过new的方式来实现实例。

    举个例子,child1,child2都是Mother的孩子,且是双胞胎。(虽然不是很好,但是还是很能说明问题的)

    图1

    如果有一天,发现孩子的父亲其实是Baba,那么就要修改每一个孩子的father属性。

    图2

    也就是说修改了其中一个孩子的father属性不会影响到下一个,属性的值无法共享。正是这个原因才提出来prototype属性,把需要共享的属性放到构造函数也就是父类的实例中去。

    __proto__

    __proto__属性是每一个对象以及函数都隐含的一个属性。对于每一个含有__proto__属性,他所指向的是创建他的构造函数的prototype。原型链就是通过这个属性构件的。

    想像一下,如果一个函数对象(也称为构造函数)a的prototype是另一个函数对象b构建出的实例,a的实例就可以通过__proto__与b的原型链起来。而b的原型其实就是Object的实例,所以a的实例对象,就可以通过原型链和object的prototype链接起来。

    图3

    如果要理清原型和原型链的关系,首先要明确一下几个概念:

    1.JS中的所有东西都是对象,函数也是对象, 而且是一种特殊的对象

    2.JS中所有的东西都由Object衍生而来, 即所有东西原型链的终点指向Object.prototype

    3.JS对象都有一个隐藏的__proto__属性,他指向创建它的构造函数的原型,但是有一个例外,Object.prototype.__proto__指向的是null。

    4.JS中构造函数和实例(对象)之间的微妙关系。

    构造函数通过定义prototype来约定其实例的规格, 再通过 new 来构造出实例,他们的作用就是生产对象。

    图4

    那么Object的__proto__指向的是Function.prototype,也即是:Object.__proto__ === Function.prototype //true。

    下面再来看Function.prototype的__proto__指向哪里?因为JS中所有的东西都是对象,那么,Function.prototype 也是对象,既然是对象,那么Function.prototype肯定是通过Object创建出来的,所以,Function.prototype.__proto__ === Object.prototype //true

    综上所述,Function和Object的原型以及原型链的关系可以归纳为下图。

    图5

    对于单个的对象实例,如果通过Object创建,var obj = new Object();那么它的原型和原型链的关系如下图:

    图6

    如果通过函数对象来创建,

    图7

    那JavaScript的整体的原型和原型链中的关系就很清晰了,如下图所示:

    图8

    转自  https://segmentfault.com/a/1190000014717972

    相关文章

      网友评论

          本文标题:2018-09-13

          本文链接:https://www.haomeiwen.com/subject/njwwgftx.html