深刻理解JavaScript系列:史上最清晰的JavaScript的原型讲解

  一提及JavaScript就要谈的几个问题,原型就是其中的一个。说了句大话,史上最清晰。原本是想按照大纲式的行文写一下,但写到后边感受其实就一个概念,没有什么条理性,因此下面就简单按照概念解释的模式谈下这个问题。javascript

1.JavaScript的原型是什么?java

  原型,首先他是个对象。和在以对象为核心的JavaScript这门语言中的其余普通对象来讲同样,只不过他的角色有点特殊。但首先要明白他就是一个对象,是一个无序的属性和值的序列对。函数

2.谁会具备原型这个对象?this

  全部的对象(包括函数这个对象)在默认的状况下都有一个原型对象。这句话的理解就和普通对象中再嵌套拥有对象是一个意思。prototype

  由于原型自己也是对象,因此每一个原型自身又有一个原型对象(属性继承就是这么来的)。照这句话下去的话会成为一个无限继承的模式,因此必定会有一个结束点。因此例外来了,当对象原型追溯到原型链的最顶端的时候,这个最顶端的位置也就是在这种层层向上的关系到了Object这个构造函数的prototype,Object函数的的prototype对象以下图:对象

 

  从图中能够看到,Object的属性里已经没有了__proto__。至于什么是__proto__,下边会讲。blog

3.__proto__和prototype分别是指什么?继承

  每个对象都有一个__proto__对象属性,每个函数(函数也是对象)都有一个 prototype对象属性,因此总结来讲就是每个对象有一个__proto__,而每个函数都有一 个prototype,但同时他又是一个对象,因此函数也会有__proto__。ip

4.__proto__和prototype的关系是怎么样的?原型链

  首先明白对象是怎么来的?对象无非是构造函数构造出来的或者是字面直接量的形式。

  构造出来的对象的__proto__指向构造该对象的构造函数的prototype;字面直接量的对象的__proto__指向该对象类型所对应的的构造函数的prototype。 

  总结来讲就是对象的__proto__指向该对象所对应的构造函数的prototype。

5.不一样函数的prototype分别是什么?

  其实这是两个问题,第一先回答不一样函数。

  首先JavaScript中只要是函数,均可以用new关键字看成构造函数来使用。可是,有些函数是咱们本身实现的,还有一些函数是JavaScript语言标准里已经规定内置实现的。这些函数包括Array、Boolean、Date、Number、String、RegExp、Math。这里会有一个问题就是Math他是一个对象而不是函数,你能够去typeof检测一下。除去Math以后剩余的这些内置构造函数的prototype属性也是语言内置实现的,好比Array里咱们经常使用的那些pop、push、shift这些方法,都通通包括在Array这个构造函数的prototype对象属性里。除了上面提到的内置构造函数外,其他的函数都是咱们本身定义的函数,他们也会有prototype属性,可是若是咱们不显示的去给prototype赋值的话,他就是一个空对象。

  接下来回答第二个问题,prototype是什么。

  其实上面已经说的很清楚了,prototype是函数的一个固有属性,即只要是个函数都会有的属性,内置的构造函数已经有实现好的prototype,它里边包括各类方法或者属性。而咱们本身实现的函数也一定会有一个prototype属性,可是若是咱们不显示赋值的话,他就是一个空对象。

6.那咱们所说的原型和原型继承究竟是什么意思?

  若是你一字不落的看完上边的全部概念并且能理解到80%以上,就应该很天然的得出这个问题的答案了。

  咱们通常所说的原型就是对象的原型,对象的原型是指_proto_这个对象。而全部的对象的继承也是经过他来实现的。第4个问答中已经很明确了,__proto__指向该对象的构造函数的prototype,而该对象的构造函数的prototype做为对象会拥有一个__proto__,而这个__proto__又指向他的构造函数的prototype,层层向上,直到__proto__指向Object这个最顶端的函数对象的prototype,也就是第二条的图所示的便结束。

  如上即是JavaScript经过原型继承的一个解释。

总结:咱们该怎么掌握原型这个概念。

  掌握一个东西,无非也就是 是什么,怎么样,怎么用这三点。

  是什么。

  首先明白__proto__和prototype,对象都会有__proto__,包括函数对象,函数对象除了__proto__,还拥有prototype。

  原型是一个对象,指__proto__,每一个对象都会拥有这个属性。__proto__指向该对象构造函数的prototype。__proto__的层层向上追溯的过程就是继承的过程,直到追溯到最顶端即Object这个构造函数的prototype。

  怎么样。

  怎么样也就是为何的意思,原型之因此存在,是基于JavaScript这门语言的面向对象思想来讲的。像其余语言都会有OO和继承等这些特性,JavaScript虽为脚本语言,灵活却不失功用,这个是他实现面向对象和继承的一个思想。能够简单的理解为此。

  怎么用。

  这个是个很大的话题,能够另开一篇文章来阐述。这里只是简单的举几个例子。

  若是仅仅只是由于为了给一个实例添加属性而使用原型是没有多大意义的,这和直接添加属性到这个实例是同样的,假如咱们已经建立了一个实例对象 ,咱们想要继承一个已经存在的对象的功能好比说Array,咱们能够像下面这样作:

var a = [1, 2];
 a.__proto__ = Array.prototype;
 console.log(a.length); //2

  又好比咱们本身实现了一个构造函数,上面已经说到,本身实现的函数的默认prototype是一个空对象,因此由这个构造函数建立生成的对象的__proto__指向的是一个空对象。咱们这时候就能够用prototype来继承或者实现一些事情。

var MyFun = function (x, y) {
        this.x = x;
        this.y = y;
    };
MyFun.prototype.getArea = function () {
        return this.x * this.
}
var obj = new MyFun(2, 3);
var area = obj.getArea();
console.log(area); //6

  写完才发现,可能这是史上最不清晰的阐述。但若是你对原型已经有了只知其一;不知其二却仍是有点模糊的话,好好的从头读到结尾,你会发现,原来掌握这个概念也是这么简单。

  完!祝好运。

相关文章
相关标签/搜索