爲何要有原型html
用構造函數生成實例對象時,缺點是沒法共享屬性和方法。
segmentfault
每個實例對象,都有本身的屬性和方法的副本。即每生成一個實例對象時,js都會爲實例分配一個內存,用來存儲那些公共的屬性和方法。這不只沒法作到數據共享,也是極大的資源浪費函數
prototype屬性就是用來解決這個問題的spa
prototype屬性包含一個對象,全部實例對象須要共享的屬性和方法,都放在這個對象裏面;那些不須要共享的屬性和方法,就放在構造函數裏面.net
實例對象一旦建立,將自動引用prototype對象的屬性和方法。即實例對象的屬性和方法,分爲兩種,一種是本地的,另外一種是引用的prototype
原型(prototype)code
每個構造函數都有一個prototype屬性,指向另外一個對象。這個對象的全部屬性和方法,都會被構造函數的實例繼承。htm
原型鏈對象
每個對象都會有一個指向它的原型(prototype)對象的內部連接(__proto__)。每一個原型對象又有本身的原型,直到某個對象的原型爲null爲止,組成這條鏈的最後一環。blog
Object
js中全部的對象都是Object的實例,並繼承Object.prototype的屬性和方法。
__proto__
定義普通對象的時候,就會生成一個_proto_,指向本身構造函數的prototype對象。(每個對象都會有的一個屬性)
function Person(){}; var p = new Person();
Person.prototype.antion = function(){
console.log(123);
} consol.log(p._proto_ === Person.prototype); //true console.log(p.__proto__); //{anition:f, constructor:ƒ, __proto__:Object}
注意:proto左右是英文狀態下的兩個下劃線!!!
prototype
擁有內部方法的對象纔有的屬性(這個屬性指向一個對象,也能夠稱其爲對象),例如函數,對象的方法,Object(內置方法爲toString、valueOf)。指向一個原型對象,能夠訪問
指向的這個原型對象其實就是自身的原型,能夠爲這個原型添加屬性和對象(方法),甚至能夠指向一個現有的對象
函數在被定義的時候就擁有了一個prototype對象
function Person(){}; var p = new Person();
console.log(Person.prototype); //{func:f, constructor:f, __proto__:Object}
二、Object.prototype 是原型鏈上最後一個有屬性的原型,也就是說,Object.prototype 的原型是 null。全部對象都繼承了 Object.prototype 的屬性,咱們也能夠向 Object.prototype 中添加屬性
function Person(){};
var p = new Person(); Object.prototype.F = function(){ console.log(「我是最後一個原型了~」); }
p.F(); //「我是最後一個原型了~」
Person.F(); //「我是最後一個原型了~」
//p爲何有 F 方法呢?覺得它會沿着 __proto__ 一層一層向上尋找,直到找到 Object.prototype
//p.__proto__指向Person.prototype,p.__proto__.__proto__ === Person.prototype.__proto__ === Object.__proto__
三、prototype 對象的另外一個屬性是constructor,這個屬性指向了函數自己,也就是它本身的構造函數。
圖示
參考:
http://www.javashuo.com/article/p-qvktecag-bb.html