JS對象中的構造函數和實例原型不一樣嗎?
function OMakeNewCar(){
}
var car = new OMakeNewCar;
OMakeNewCar是構造函數其中,OMakeNewCar.prototype指向實例原型,但是它具體到底是什麼呢?是Function對象,還是Object對象?我測試時這樣輸:
OMakeNewCar.prototype.mm = 1;
alert(Function.mm);//undefinedalert Object.mm得到的提示一樣,不過如果輸 alert(OMakeNewCar.prototype.mm),輸出1,說明賦值以後它還是在內存中的,但是 OMakeNewCar的原型既不是Function對象也不是Object對象,它到底是什麼?car是構造函數 OMakeNewCar 的實例,為什麼car.prototype指向的不是構造函數?謝謝!
我想,題主對於構造函數和原型對象的概念理解的還不夠透徹。
所謂構造函數,是生成一個對象的模板,是生成對象的函數。一個構造函數,可以生成多個實例對象,每個實例對象都有相同的結構。
接以上的例子,當你使用new操作符調用Keith構造函數時,會經歷以下步驟:
1.創建一個空對象,作為將要返回的實例對象 2.將空對象的原型指向構造函數的prototype屬性,也就是Keith構造函數的prototype屬性。 3.將空對象賦值給構造函數內部的this關鍵字,也就是this關鍵字會指向實例對象。 4.開始執行構造函數內部的代碼。題主的第一個問題是,Keith.prototype指向實例原型,但是它具體指向什麼?
當然了,person2實例對象也是如此。
所以,題主所說的構造函數的原型 Keith.prototype指向的不是Function,也不是Object,而是Object.prototype。
另外。當為構造函數定義原型屬性,並且訪問原型屬性時,
因為mm是原型Keith.prototype上定義的一個屬性。Function對象沒有定義mm屬性,所以返回了默認值undefined。
但是這樣訪問一個原型屬性是沒有意義的。而是應該通過對象實例來訪問原型屬性。
person1實例對象本身是沒有mm屬性的,所以會在原型Keith.protoype上查找。在原型找到了mm屬性,所以就繼承了原型的mm屬性。若原型上沒有mm屬性,會繼續在原型的原型上查找,直到null對象,若還是沒有該屬性,則返回undefined。
回答題主的最後一個問題:car是構造函數 OMakeNewCar 的實例,為什麼car.prototype指向的不是構造函數?
從例子上面的說明,我想題主應該知道原因了。構造函數只是提供創建對象的模板,而不是原型對象。所以person1.prototype指向的不是構造函數,而是構造函數的原型。
希望題主能明白。
謝謝。
個人博客:Uncle-Keith - 博客園1、OMakeNewCar.prototype 指向構造函數 OMakeNewCar 自身的原型對象。
要理解這一點,樓主需要先了解一些東西。
每在屏幕上敲出來一個函數,啥構造不構造的,根本不用管,系統都會為這個函數創建一個 prototype 屬性。這個 prototype 屬性指向一個對象,這個對象就是此函數的原型對象。
原型對象哪來的,系統分配的唄,當然這裡要注意一點,原型對象可不是 Function 或 Object,而是系統會為每個函數創建屬於它自己的原型對象,因此每個函數的原型對象都是不同的。
那原型對象里都有啥,其實很簡單,如果你不操作這個原型對象,那麼一開始它只包含一個屬性:constructor。當然可以在原型對象上添加你想添加的任何屬性。
constructor 屬性幹啥用的?指向函數自身。
回到問題,OMakeNewCar.prototype 指向的就是函數 OMakeNewCar 的原型對象。
如果想看看此時 OMakeNewCar 原型對象中的 constructor 屬性,可以這樣寫 OMakeNewCar.prototype.constructor,樓主可以想到 OMakeNewCar.prototype.constructor 就是 function OMakeNewCar() {}。
2、car 是構造函數 OMakeNewCar 的實例,但 car 沒有 prototype 屬性。
樓主還是需要先了解以下的東西。
只有函數才有 prototype 屬性,其他對象均沒有此屬性。樓主一定會問,那 car 不是函數嗎,答案是 car 不是函數,而只是一個普通對象。
簡單解釋一下 var car = new OMakeNewCar(); 這段代碼。
先看等號右邊 new OMakeNewCar(),別管什麼 new 不 new 的,這不過就是在調用 OMakeNewCar 這個函數,函數調用後都有返回值(沒有明確返回值的函數,返回值是undefined)。那函數前面加了 new 調用,返回值是啥呢?解決樓主問題的關鍵點來了,返回值是一個對象。
再看等號的左邊,從函數中返回的對象被賦值給了 car。因此,此時的 car 就代表了返回的對象。car 代表的對象只是一個普通對象,所以沒有 prototype屬性。
這裡需要插句話,樓主為了測試加了這樣一句代碼 OMakeNewCar.prototype.mm = 1;也就是在構造函數原型上加了 mm 這個屬性,並把 1 賦值給了這個屬性。
可以告訴樓主,下面我寫的這句代碼也是可以正確運行的
alert(car.mm); // 彈出 1接下來,需要跟樓主介紹任何對象上的都有的一個屬性,叫做 __proto__,跟函數上的 prototype 屬性有點像,沒錯,確實有點像。
這個屬性幹嘛用的?指向該對象構造函數上的原型對象,即和構造函數的 Prototype 屬性指向的是同一個對象。
回到問題,car 的構造函數是 OMakeNewCar,那麼 car.__proto__ 指向的就是 OMakeNewCar 的原型對象。
看看下面的這兩句代碼
OMakeNewCar.prototype.mm = 1;alert(car.mm);mm 屬性 car 對象上原本沒有,但其構造函數的原型對象上有,所以在 car 上找不到 mm 時,系統就會通過 __proto__ 找到其構造函數的原型對象,然後找到了 mm 屬性。當然實際寫代碼時不要加 __proto__ 屬性,直接寫 car.mm 就行,如果在 car 對象中找不到 mm,系統就會自動到其構造函數的原型對象上去找。
car是實例對象,沒有prototype這個引用屬性。想要訪問他的構造函數的原型
可以car.__proto__.mm =xxx來賦值,構造函數中的原型對象是繼承Object.prototype的(構造函數)__proto__ === Object.prototype,對象構造函數的prototype 是終點,Object.prototype.__proto__ === null。因為Object是構造函數,Object.__proto__指向Function.prototype,Function.prototype.__proto__ === Object.prototypeFunction.__proto__ === Function.prototypeObject.prototype才是JS中的爸爸。這是js下的一個大坑呀推薦查閱下這個網址JS原型與原型鏈終極詳解而且car是由OMakeNewCar 實例化而來,並非構造函數,不存在prototype屬性!
推薦閱讀:
※如何有效快速的學習HTML/CSS/JS?
※都說學習原生 JS 很重要,在實際網站前台應用開發中哪些是 jQuery 這些庫無法解決的?
※h5 css js學習時間加起來大概需要多少時間,推薦幾個網上學習課程?
※自己寫HTML用Cordova打包與用AppCan、Dcloud、WeX5、ApiCloud有何區別?
※你為什麼選擇做前端?
TAG:HTML | JavaScript | ECMAScript |