上一篇談new關鍵字也是給這一篇寫關於原型的文章買個伏筆,我對原型的理解可能會有偏差,如有錯誤,望指正一定修改,望各位道友如果想真正的理解原型的概念一定要再看完各方言論再回歸教材。 言歸正傳談原型,首先原型是一個對象,無論什麼時候,只要創建了一個函數,就會按照規則創建一個Prototype屬性,這個 ...
上一篇談new關鍵字也是給這一篇寫關於原型的文章買個伏筆,我對原型的理解可能會有偏差,如有錯誤,望指正一定修改,望各位道友如果想真正的理解原型的概念一定要再看完各方言論再回歸教材。
言歸正傳談原型,首先原型是一個對象,無論什麼時候,只要創建了一個函數,就會按照規則創建一個Prototype屬性,這個屬性指向函數的原型對象,在預設情況下,所有的原型對象都會有一個constructor屬性,這個屬性又指向函數的原型對象。先來段代碼
function Person(){} Person.prototype.name = "王方"; Person.prototype.age= 23; Person.prototype.job= "前端開發"; Person.prototype.sayName= function(){ alert(this.name) } var person1 = new Person(); person1.sayName(); //“王方” var person2 = new Person(); person2.sayName(); //“王方”
在上面的例子中,Person.prototype.constructor指向Person,通過這個構造函數,我們還可以繼續為原型添加其他屬性以及方法。解釋原型,用例子遠比用言語解釋要好一些。
繼續看
//創建一個函數b var b = function(){ var one; } //使用b創建一個對象實例c var c = new b(); //查看b 和c的構造函數 b.constructor; // function Function() { [native code]} b.constructor==Function.constructor; //true c.constructor; //實例c的構造函數 即 b function(){ var one; } c.constructor==b //true //b是一個函數,查看b的原型如下 b.constructor.prototype // function (){} b.__proto__ //function (){} //b是一個函數,由於javascript沒有在構造函數constructor和函數function之間做區分,所以函數像constructor一樣, //有一個原型屬性,這和函數的原型(b.__proto__ 或者b.construtor.prototype)是不一樣的 b.prototype //[object Object] 函數b的原型屬性 b.prototype==b.constructor.prototype //fasle b.prototype==b.__proto__ //false b.__proto__==b.constructor.prototype //true //c是一個由b創建的對象實例,查看c的原型如下 c.constructor.prototype //[object Object] 這是對象的原型 c.__proto__ //[object Object] 這是對象的原型 c.constructor.prototype==b.constructor.prototype; //false c的原型和b的原型比較 c.constructor.prototype==b.prototype; //true c的原型和b的原型屬性比較 //為函數b的原型屬性添加一個屬性max b.prototype.max = 3 //實例c也有了一個屬性max c.max //3
上面的例子中,對象實例c的原型和函數的b的原型屬性是一樣的,如果改變b的原型屬性,則對象實例c的原型也會改變。
prototype與__proto__
關於它們的區別,我就只在一方面來講吧,如上面例子,給b的prototype添加屬性值,實例對象也可以繼承到,再給個例子
var A = function(name) { this.name = name; } var a = new A('alpha'); a.name; //'alpha' A.prototype.x = 23; a.x; //23
因為在a實際被創建之後,a.__proto__是一個對A.prototype 的一個引用。所以修改原型屬性,就會有改變。
但是如果對A的原型進行修改,並不會反應到A所創建的實例a中,如下麵的例子
var A = function(name) { this.name = name; } var a = new A('alpha'); a.name; //'alpha' A.prototype = {x:23}; a.x; //null
哈,說了這麼多,原型到底能做什麼呢?
原型的用途
因為每個對象和原型都有一個原型(註:原型也是一個對象),對象的原型指向對象的父,而父的原型又指向父的父,我們把這種通過原型層層連接起來的關係撐為原型鏈。
通過原型以及原型鏈,可以讓所有的對象實例共用它所包含的屬性和方法,就不必在構造函數中定義了。
限於筆者的水平有限,對於原型的介紹也比較粗糙,不足之處有很多,望各位道友指正。