原型是一个对象,每一个函数对象(在javascript 之对象中说过函数也是对象 )都有一个属性(prototype)指向这个对象--原型对象,这个对象的做用是让全部对象实例共享原型对象中的属性、方法。即咱们能够把公共的属性、方法写在这个原型中,因此说js中的继承是基于原型实现的;javascript
每一个构造函数都有一个原型对象,原型对象包含一个指针指向构造函数,而实例包含一个指向原型对象的内部指针;java
1 function Person(name,age){ 2 this.name=name; 3 this.age=age; 4 } 5 console.dir(Person);
如图:编程
Person 有个属性prototype 指向原型对象浏览器
原型对象经过constructor 指向函数对象性能优化
Object.getPrototypeOf() 能够查看MDN的介绍:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf
函数
原型链是一种机制,指的是JavaScript每个对象、包括原型对象都有一个内部的[[proto]]属性,它指向建立它的函数对象的原型对象。这个属性是编程不可见的(虽然ES6标准中开放了这个属性,然而浏览器对这个属性的可见性的支持不一样)。性能
当一个对象须要引用一个属性时,JavaScript引擎首先会从这个对象自身的属性表中寻找这个属性标识,若是找到则进行相应读写操做,若是没有在自身的属性表中找到,则在_proto_属性引用的对象(原型对象)的属性表中查找,如此往复,直到找到这个属性或者_proto_属性指向null为止(object prototype )。优化
对象的_proto_的引用链,称为原型链。this
注意:有一个性能优化的问题:原型链越深,耗费的时间越多,同理做用域链也是这样。spa
原型链的存在,主要是为了实现对象的继承。
理解原型链,须要从几个概念入手。
在JavaScript中,函数也是对象。
当定义一个函数对象时,会包含一个内部属性,叫prototype称之为原型对象。
1 //普通对象 2 var a = {}; 3 console.log(a.prototype);//undefined
在建立对象的时候,都会有一个[[proto]]的内部属性,用于指向建立它的函数对象的prototype(函数对象prototype 指向函数的原型对象)。原型对象也有[[proto]]属性,所以在不断的指向中,造成了原型链。
举个例子来讲,咱们将对象F的原型对象修改一下,就能够清楚看到上述的关系
1 function F(){}; 2 var f = new F(); 3 console.log(f.__proto__);
当使用new去调用构造函数时,至关于执行了
1 var o = {}; 2 o.__proto__ = F.prototype; 3 F.call(o);
在原型链的实现上,new起到了很关键的做用。
原型对象prototype上都有个constructor属性,指向它的函数对象,如上图。
在实际运用中,常常这样写:
1 function F(){}; 2 F.prototype = { 3 constructor : F, 4 doSomething : function(){} 5 }
这里要加constructor是由于重写了原型对象,以前的constructor属性跟重写的原型对象没有任何关系,因此须要本身手动补上。
1 function F(){ 2 this.name = 'zhang'; 3 }; 4 var f1 = new F(); 5 var f2 = new F();