1.
我們建立的每個函式(或稱建構函式或物件)都有乙個 prototype(原型)屬性,這個屬性是乙個物件(這個物件下有個prototype屬性,而這個屬性其實是另外乙個物件的引用,這個屬性就是乙個物件),它的用途是
包含可以由特定型別的所有例項共享的屬性和方法(prototype共享放到其中的屬性和方法,無論例項化多少物件,屬性和方法都是共享的。這樣有好處也有壞處。)。邏輯上可以這麼理解:prototype 通過
呼叫建構函式而建立的那個物件的原型物件。使用原型的好處可以讓所有物件例項共享它所
包含的屬性和方法。也就是說,不必在建構函式中定義物件資訊,而是可以直接將這些資訊
新增到原型中。
//建構函式宣告物件方式
function box(name,age) //建構函式函式體內什麼都沒有,這裡如果有,叫做例項屬性,實習方法
box.prototype.name = 'lee'; //原型屬性 原型裡新增屬性
box.prototype.age = 100;
box.prototype.run = function () ;
比較一下原型內的方法位址是否一致:
var box1 = new box();
alert(box1.name); //輸出lee
alert(box1.run()); //輸出lee執行中
var box2 = new box();
alert(box1.run == box2.run); //true,方法的引用位址保持一致
以上兩個例子說明:
如果是例項方法,不同的例項化,他們的方法位址是不一樣的,是唯一的
2.
為了更進一步了解建構函式的宣告方式和原型模式的宣告方式,我們通過圖示來了解一
下:
(1)建構函式方式中
box1和box2 的例項屬性例項方法在記憶體中是不共享的,box1的name屬性和box2的name屬性的位址是不同的
(2)原型方式中
function box(){}
box.prototype.name = 'lee';
box.prototype.age = 100;
box.prototype.run = function () ;
var box1 = new box();//box例項有了,但是裡面為空,實際上裡面有個自帶的屬性_proto_
var box1 = new box();
alert(box1.prototype);// undefined 這個屬性是乙個物件,訪問不到
alert(box1._proto_); // 輸出 object 這個屬性是乙個指標,指向prototype原型物件,但是_proto_在ie瀏覽器中是不支援的
建立的每個函式都有乙個 prototype(原型)屬性,但是這裡訪問不到,應該訪問的是那個指標_proto_
_proto_實際上就是prototy,只不過他是個指標屬性,指向prototype物件
在原型模式宣告中,多了兩個屬性,這兩個屬性都是建立物件時自動生成的。__proto__
屬性是例項指向原型物件的乙個指標,它的作用就是指向建構函式的原型屬性 constructor,而constructor指向box,
通過這兩個屬性,就可以訪問到原型裡的屬性和方法了。
ps:ie 瀏覽器在指令碼訪問__proto__會不能識別,火狐和谷歌瀏覽器及其他某些瀏覽器
均能識別。雖然可以輸出,但無法獲取內部資訊。
alert(box1.__proto__); //[object object]
alert(box1.constructor); //輸出 function box() 。constructor是構造屬性,可以獲取建構函式本身 作用是通過被原型指標定位,然後得到建構函式本身,其實就是做乙個連線的作用,就是物件例項對應原型物件的作用
以下圖是在控制台打出的:
判斷乙個物件例項(物件引用)是否指向了該建構函式的原型物件,可以使用 isprototypeof()方法來測試。只要例項化了,他是自動指向的。
alert(box.prototype.isprototypeof(box1)); //true 只要例項化物件,即都會指向
例如:var obj = new object();
alert(object.prototype.isprototypeof(obj)); //true
說明只要例項化了,就預設指向
alert(object.prototype.isprototypeof(box1)); //true 因為所有的例項都是object
alert(box.prototype.isprototypeof(obj)); //false
4.
原型模式的執行流程:
1.先查詢建構函式例項裡的屬性或方法,如果有,立刻返回;
2.如果建構函式例項裡沒有,則去它的原型物件裡找,如果有,就返回;
function box(){} // 建構函式函式體內什麼都沒有,如果有,叫做例項屬性和例項方法
box.prototype.name = 'lee'; //原型屬性
var box1 = new box();
alert(box1.name); //輸出 lee 建構函式例項裡沒有,則去它的原型物件裡找
box1.name = 'jack'; //例項屬性 並沒有重寫原型
alert(box1.name); //輸出 jack 就近原則 先查詢建構函式例項裡的屬性或方法,如果有,立刻返回
var box2 = new box();
alert(box2.name); //例項屬性不會共享,所以box2訪問不到例項屬性,只能訪問到原型屬性
delete box1.name; //刪除例項中的屬性
alert(box1.name); //輸出lee
delete box.prototype.name //刪除原型中的屬性
alert(box1.name); // undefined
box.prototype.name = 'kk'; //覆蓋原型中的屬性
alert(box1.name); //輸出kk
如果:function box()
var box = new box();
alert(isproperty(box, 'name')) //true,如果原型有
物件導向程式設計 2 類與原型
1.用函式代替物件儲存變數 變數const obj1 函式 實際上最終還是放在物件裡 const getobj 首先,變數儲存,在你申明的時候就已經把這個變數的內容存在記憶體裡的.用變數,存的就是變數,用函式,存的就是函式.換而言之,物件中存了a,b,c.而函式中並沒有,函式返回的那個物件只有在函式...
物件導向與原型三
function box function desk 通過原型鏈整合,超型別例項化後的物件例項,賦值給子類的原型屬性 new box 會將box構造裡的資訊和原型裡的資訊都交給desk desk.prototype new box desk繼承box,通過原型形成鏈條 var desk new de...
物件 原型與原型鏈
object.definepropertylet obj object.defineproperty obj,key1 console.log object.getownpropertydescriptor obj,key0 console.log object.getownpropertydesc...