好程序員web前端培訓分享Javascript中原型屬性

好程序員web前端培訓分享Javascript中原型屬性html

  本文將從如下三個方面講解原型屬性前端

一、 理解指針html5

二、 理解原型程序員

三、 用原型的方式完成繼承web

  如下爲詳細內容:函數

一、 理解指針學習

  要理解JAVASCRIPT中的原型,先理解指針,在C/C++中,會提到指針,其實,指針不該該屬於C/C++的專利,上篇文章中,提到的引用類型(也是不少面嚮對象語言中的數據類型的叫法),就是指針。this

C/C++中對指針的解釋:指針就是地址。地址爲什麼物?prototype

  地址:是計算機對內存每一個存儲單元的管理方式。在計算機的內存中,存儲着若干數據,計算機的CPU是如何讀取內存中的數據的?指針

  計算機的每一個存儲單元都有一個編號,就像到超市存包時,每一個存包的格子都有一個編號,這個編號就是地址,內存的地址。超市每一個格子爲何要有編號,目的就是爲了方便服務員進行查找(根據編號進行查找),計算機每一個存儲單元爲何會有一個編號,目的也是爲了CPU查找內存。

http://www.goodprogrammer.org/html5_class.shtml

  若是某個內存中直接存儲的是數據,則這種數據是基本類型的數據,若是某個內存中存儲的是其它內存的編號(數據),那麼這種數據就叫引用類型的數據。

二、 理解原型

a) 原型(屬性)的概念

JAVASCRIPT中的函數也是對象(若是不懂函數也是個對象,請百度JAVASCRIPT中函數是功能完整的類),每一個函數都有一個原型(prototype)屬性,這個屬性是指針類型。原型屬性是對象類型,因此,也能夠叫原型對象,原型就是模子,模型。函數何來原型,其實理解原型(模型)更應該用構造函數來理解會更好。

  構造函數是用來構造實例的,每次用new運算符調用構造函數產生一個實例時,模型就會起做用。就像咱們要造一個塑料製品(如:杯子,電腦顯示器的外殼,打印機的外殼等),都有一個模具,只要是同一個模具作出來的物體,都很是類似。因此,百度上對模具的解釋:模具的俗稱。經常使用於比喻具備大量類似點的兩個或多我的或者事物。

b) 原型模式建立對象(把構造函數和原型模式合在一塊兒)

  用同一個構造函數構造的實例,具備不少的共同點(共同的屬性或者函數),這些共同點就是不少書籍描述的「全部實例共享的屬性和方法」。這些共同點就是用prototype屬性進行維護的。具體的作法就是:全部實例共享的屬性和方法用prototype屬性進行表示。

  如:

function Person(id,name,sex){

//在構造函數裏寫的是每一個實例特有的屬性(屬性值不同)

this.id =id;

this.name = name;

this.sex = sex;

}

//全部人的國籍都是中國,國籍屬性就用prototype來表示

Person.prototype.country = 「中國」;

//全部人吃的邏輯都同樣。因此,吃的函數也用prototype來表示

Person.Prototype.eat = function(str){

alert(this.name+」在吃」+str+」,天在看……」);

}

var p1 = new Person(「007」, 「樂樂」, 「女」);

var p2 = new Person(「008」, 「寶寶」, 「男」);

Console.log(p1.country);//中國

Console.log(p2.country); //中國

p1和p2兩個實例的country屬性值都是中國,由於它們兩個是一個構造函數實例化出來的(一個模子「刻」出來的)。

  以下是示意圖,其中帶箭頭的線表示指向。

好程序員

  圖中能夠看出:

1)、在Person構造函數的prototype屬性中有個constructor屬性,指向了構造函數自己。constructor屬性到底有何用,你們先把它save到大腦中,後面給你們講解。

2)、兩個實例p1和p2指向了Person構造函數的prototype屬性,跟Person構造函數沒有直接關係。

3)、兩個實例p1和p2都有[[prototype]]屬性。實例靠着 [[prototype]]屬性找到它所對應構造函數的原型,也是靠它來找到,原型中的屬性的。注意, [[prototype]]屬性不能直接在代碼中使用。

c) 原型(類型的)屬性和實例(類型的)屬性

  每一個實例特有的屬性和方法存放在實例所在內存區域,也叫實例屬性,如以上例中的id,name,sex屬性。全部實例共享的屬性和方法,都在原型(prototype)對應的內存區域,也叫原型的屬性,如上例中的country。

i. 原型(類型的)屬性變成實例(類型的)屬性

  這裏有點疑惑,隨着時間的推移,有的對象的原型屬性的值會發生變化?

  如:寶寶年輕時,以爲俄羅斯的美女多,決定定居俄羅斯了。即p2的country(國籍)的值爲俄羅斯。那該如何是好,改仍是不改?改了會不會影響其它對象的country屬性的值。不改,又不能知足需求。看來,JAVASCRIPT在這方面仍是考慮到了。能夠改,並且不會影響其它對象的屬性值。

  還有,若是出現了實例屬性和原型屬性重名的狀況,用實例來訪問該屬性時,到底訪問的是實例屬性仍是原型屬性。這個JAVASCRIPT中解決了。

  如何解決上面的問題的。在JAVASCRIPT中,當給原型屬性賦值時,在對應實例中會增長了一個同名的實例屬性,而後把值賦給實例屬性,而原型屬性的值不受影響。當訪問該屬性時,先在實例屬性中尋找,若是找不到,再在原型屬性中找。

  如如下代碼:

P2.country = 「俄羅斯」;

  執行時,內存會變成以下:

好程序員

  在p2的實例中增長一個country實例屬性,內容爲「俄羅斯」(圖中紅色的框裏)。這樣,代碼p1.country依然去找實例屬性的值「中國」。而p2.country先在實例屬性中找country,找到了,就不用去原型屬性中去找了。即,當實例訪問屬性時,會先在實例的內存中去尋找,若是找不到就會到原型的內存中去尋找。

ii. 刪除實例(類型的)屬性

  隨着寶寶年齡的增加,對美女沒有了興趣,並且以爲仍是在本身的國家好,又想回來。即p2.country的值爲」中國」,這時候是能夠利用原型裏的屬性值,怎麼辦?沒事,使用delete p2.country就會把p2的實例屬性country刪除掉。

  放心吧,delete是不能刪除掉原型的屬性的。

三、 繼承時原型的理解(原型鏈)

  原型鏈是ECMAScript中實現繼承的一種方式。若是不懂繼承,請先百度,理解繼承的概念。

  原型繼承的基本思想是讓原型屬性(對象)指向另一個類型的的實例。

  如:

  父對象:人

function Person(id,name,age){

this.id = id;

this.name = name;

this.age = age;

}

Person.prototype.eat = function(str){

alert(this.name+"在吃"+str);

}

  子對象:程序員

function Programmer(languages){

this.languages = languages;

}

//此句話使用原型實現了繼承,子對象Programmer的原型屬性指向了父對象Person的實例。

Programmer.prototype = new Person(「008」, 「寶寶」, 「20」);

Programmer.prototype.writeCode=function(){

alert(this.name+"一邊努力地寫着代碼,一邊想着‘多寫代碼,多掙錢’");

}

  從圖中能夠看出,子對象Programmer擁有了父對象的屬性(id,name,age)和方法(eat)。本身特有的屬性languages和方法writeCode()。成功完成了繼承。

  特別要注意,子對象完成了繼承關係後,再給子對象的原型中增長屬性和方法。即,先寫代碼Programmer.prototype = new Person(「008」, 「寶寶」, 「20」); 再寫代碼:

Programmer.prototype.writeCode=function(){

alert(this.name+"一邊努力地寫着代碼,一邊想着‘多寫代碼,多掙錢’");

}

  不然,當子對象的prototype(原型)屬性的指向發生變化後,原來在prototype(原型)屬性中所寫屬性和方法就會丟失。

  原型鏈繼承:當B對象的原型屬性指向了A對象的實例,而C對象的原型屬性指向B對象的實例時,就完成了原型鏈繼承。

  注:

一、此篇文章能夠結合JAVASCRIPT中建立對象的幾種方式進行學習。若是再能結合上篇文章《對比引用類型與基本類型》就會更好

二、此篇文章只是爲了理解prototype屬性,因此,不少的注意點並無涉及。做者更但願你們學一點,理解一點,而不是大而全。並且學習是按部就班的。先把prototype屬性理解了,再去關注注意點。

相關文章
相關標籤/搜索