經常看到一些js代碼裡面出現類似object.prototype.ctx..等之類的代碼,一直看不懂是什麼意思,偶爾到網上搜了一下也覺得很模糊,今天花了大半天時間好好研究了一下,把自己心得總結一下.
prototype是一個js的函數(function)的一個屬性也可以說成是它的一個對象,js預設每個類型都隻能有一個原形(比如var a = new Date() 這個a的類型就是Date),預設的所有的function的原形是Object(類似于java所有的對象的父類都是object),根據我的了解,主要用途有倆種.(其他的無數,體會的主要的,請不要丢雞蛋)
1.第一種是繼承..
比如: function testParent() {
this.title = "Hello World";
}
testParent.prototype.content = "I am a java programmer";
function testSon() {
this.titleSon = "Hello World";
}
//testSon繼承testParent
testSon.prototype = new testParent();
var son = new testSon();
alert(son.content);//列印的值為I am j java progranmmer;
//也可以說成 testParent是testSon的原形,可以了解為繼承關系,但是不是複制,是引用,所有testSon的執行個體全部共享一個testParent的屬性和方法.當原形(testParents)中某個原形屬性( testParent.prototype.content = "I am a java programmer";),被改變時,子類(testSon)的所有執行個體裡的content值将會改邊.是以千萬不要随意更改原形屬性,可以用覆寫的方法,例如在子類定義一個屬性或方法和父類的相同,那麼就會覆寫,如果需要父類方法時,則delete(對象.屬性名),可以删除子類的屬性,就可以取到父類屬性了. 如果需要更改testParent的原形屬性則要三思,一改下面所有執行個體引用testParent的屬性和方法全部變了,這也是prototype的缺陷所在,但是有時還是可以起到事半工倍的效果,就看用途了. 如果是自己寫的testParent則沒什麼,直接進去修改就好了,如果是其他程式員寫的還是繼承以後再覆寫吧,到時還可以delete回來. 千萬别在自己的子類testSon裡加原形屬性,這樣一來也會影響testParent和所有執行個體. 還有一種情況就是,如果是以前的程式員寫的,封裝的非常的死,基本上看不到代碼,并且以前的"父類"裡有很多方法需要用,為了達到重用的目的,恭喜你這時候可以檢測一下自己能力了,如果覺得比較強大的可以直接修改"父類"的方法或者屬性,例如:testParents.prototype.content = "I am a c++ programmer";
或者如果不是很自信的話直接加新的方法或函數就好了. testParents.prototype.newContent = "good";
2.第二種用法是針對javascript裡面的核心對象的,例如:Array, Date, Number.....等
除了一種叫做執行個體化繼承法的方法可以獲得核心對象的原型執行個體以外(這種方法也是勉強湊到一起的,執行個體化的對象和原型都不是同一個類型,違背了prototype的規則),其他的都不行,會報'object'; is not...
這時候可以按上面說的,直接再裡面添加新的方法,也可以覆寫以前的方法.
Date.prototype.getDate = function() {alert('TMD,叫你封裝')}
-_-!!
3.就是可以快速的建立1個或多個原型副本,和第一條基本類似,這裡就不具體說了.
4.可以避免構造函數重讀一個function裡的屬性.
function test(table) {
this.table = table;
this.show = function() {
alert('Hello');
}
}
這種寫發,每次new一個對象都必須運作this.show..這個方法,是以可以這樣改
function test(table) {
this.table = table;
}
test.prototype.show = function() {
alert('Hello world');
}
}
對性能比較好哦..