成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript構(gòu)造器理解

PiscesYE / 1295人閱讀

摘要:類類的概念應(yīng)該是面向?qū)ο笳Z言的一個(gè)特色,但是并不像,等高級(jí)語言那樣擁有正式的類,而是多數(shù)通過構(gòu)造器以及原型方式來仿造實(shí)現(xiàn)。因此,出現(xiàn)了構(gòu)造函數(shù)方式,它的關(guān)鍵在于構(gòu)造器概念的引入。于是,這就產(chǎn)生了構(gòu)造函數(shù)原型法的類構(gòu)造方法。

  

類 Class 類的概念應(yīng)該是面向?qū)ο笳Z言的一個(gè)特色,但是JavaScript并不像Java,C++等高級(jí)語言那樣擁有正式的類,而是多數(shù)通過構(gòu)造器以及原型方式來仿造實(shí)現(xiàn)。在討論構(gòu)造器和原型方法前,我可以看看一種叫做工廠方式的仿造方法。

工廠模式



這種方式顯然可以實(shí)現(xiàn)class的功能,但是外形上怎么也無法說它是個(gè)class以及class實(shí)例的創(chuàng)建過程。因此,出現(xiàn)了“構(gòu)造函數(shù)方式”,它的關(guān)鍵在于構(gòu)造器(Constructor)概念的引入。

構(gòu)造函數(shù)方式

構(gòu)造器(Constructor)



這個(gè)看起來有點(diǎn)類的樣子了吧(先不提那個(gè)難看的外置function)?我們發(fā)現(xiàn),那個(gè)constructor其實(shí)就是一個(gè)簡單的function,它與“工廠方式”中的createCar()區(qū)別就在于:
1、方法名大寫
2、沒有了空對(duì)象的創(chuàng)建和返回
3、使用this做引用。
那原來的那個(gè)空對(duì)象的創(chuàng)建以及返回的步驟去哪了呢?這兩個(gè)步驟,現(xiàn)在都由創(chuàng)建實(shí)例時(shí)的“new”實(shí)現(xiàn)了。“new”這個(gè)操作符負(fù)責(zé)創(chuàng)建一個(gè)空對(duì)象,然后將那個(gè)叫做構(gòu)造器的function添加到實(shí)例對(duì)象中并觸發(fā)它,這樣這個(gè)function實(shí)際上就是這個(gè)對(duì)象的一個(gè)method,function中的this指向的便是這個(gè)對(duì)象,最后將這個(gè)對(duì)象返回。根據(jù)如上分析,我們可以把這個(gè)過程簡單分解為如下代碼:


構(gòu)造函數(shù)方式雖然與高級(jí)面向?qū)ο笳Z言中的類創(chuàng)建方式已經(jīng)很接近(使用new創(chuàng)建),但是貌似那個(gè)游離在類之外的function material()其實(shí)卻是個(gè)相當(dāng)有礙觀瞻的瑕疵。我們應(yīng)該想一種辦法讓這個(gè)方法與類掛鉤,讓它成為類的一個(gè)屬性,不是全局的。于是,這就產(chǎn)生了“構(gòu)造函數(shù)+原型法”的類構(gòu)造方法。

構(gòu)造函數(shù) + 原型

從上面的構(gòu)造函數(shù)模式創(chuàng)建對(duì)象的例子上可以看到,每創(chuàng)建一個(gè)對(duì)象實(shí)例,每個(gè)對(duì)象中都有material()這個(gè)成員方法,這樣看起來是不是會(huì)浪費(fèi)內(nèi)存空間,降低執(zhí)行效率。所以JavaScript中提供了原型的方法可以解決這個(gè)問題。

  

原型:proto
在JavaScript中每個(gè)函數(shù)都有一個(gè)原型屬性,即prototype,當(dāng)調(diào)用構(gòu)造函數(shù)進(jìn)行創(chuàng)建對(duì)象的時(shí)候,所有該構(gòu)造函數(shù)原型的屬性在創(chuàng)建的對(duì)象上都可用。按照這樣的想法多個(gè)CreateCar都可以共享一個(gè)原型material.

構(gòu)造函數(shù)+原型法中,我們對(duì)于類的method期待得到的效果是:
1. 僅是類的method而不是全局的。
2. 只在類被定義時(shí)創(chuàng)建一個(gè)method實(shí)例,然后被所有類的實(shí)例共用。

由這兩個(gè)目標(biāo),我們很容易想到高級(jí)面向?qū)ο笳Z言Java的private static變量的特點(diǎn)。JavaScript沒有為我們提供這么簡單的符號(hào)來實(shí)現(xiàn)這個(gè)復(fù)雜功能,但是卻有一個(gè)屬性可以幫我們仿造出這種效果:prototype。我們先來看幾段prototype的使用代碼。


> function Car(){ } > > Car.prototype.material = "steel"; > > var car1 = new Car(); var car2 = new Car(); > > document.write(car1.material); //prints "steel" > document.write(car2.material); //prints "steel" > > //car1.prototype.material = "iron" //compile error:car1.prototype is > undefined car1.material = "iron"; > > document.write(car1.material); //prints "iron" > document.write(car2.material); //prints "steel" > document.write(Car.prototype.material); //prints "steel" > > Car.prototype.material = "wood"; var car3 = new Car(); > document.write(car1.material); //prints "iron" > document.write(car2.material ); //prints "wood" > document.write(car3.material ); //prints "wood" > document.write(Car.prototype.material); //prints "wood"

分析該段代碼前,需要明確兩個(gè)概念:對(duì)象的直屬屬性和繼承屬性。直接在構(gòu)造函數(shù)中通過this.someproperty = xxx這種形式定義的someproperty屬性叫做對(duì)象的直屬屬性,而通過如上第4行代碼那樣Car.prototype.material = "steel";這種形式定義的material屬性叫做繼承屬性。由上面這段代碼,我們可以總結(jié)出prototype屬性的如下特點(diǎn):

prototype是function下的屬性(其實(shí)任意object都擁有該屬性,function是對(duì)象的一種)

prototype屬性的值是一個(gè)對(duì)象,因此可任意添加子屬性(line 4)

類的實(shí)例可以直接通過"."來直接獲取prototype下的任意子屬性(line 9)

所有以此function作為構(gòu)造函數(shù)創(chuàng)建的類實(shí)例共用prototype中的屬性及值(ling 9,10)

類的實(shí)例沒有prototype屬性(line 12)

可以直接通過 "實(shí)例.屬性 = xxx" 的方式修改繼承屬性,修改后的值將覆蓋繼承自prototype的屬性,但此修改不影響prototype本身,也不影響其它類實(shí)例(line 15,16,17)

繼承屬性修改后,該屬性就成為類實(shí)例的直屬屬性

可以直接修改prototype的屬性值,此改變將作用于此類下的所有實(shí)例,但無法改變直屬屬性值(極晚綁定line 21-24)

  

PS:對(duì)象實(shí)例在讀取某屬性時(shí),如果在本身的直屬屬性中沒有查找到該屬性,那么就會(huì)去查找function下的prototype的屬性。

Tip:我們可以通過hasOwnProperty方法來判斷某屬性是直屬于對(duì)象還是繼承自它的prototype屬性
    car1.hasOwnProperty("material"); // true
    car2.hasOwnProperty("material"); // false
    "material" in car2;// true

構(gòu)造函數(shù)+原型方式代碼如下



這個(gè)跟高級(jí)面向?qū)ο笳Z言中的class的樣子更~加類似了吧?上述寫法只是在“語義”上達(dá)到了對(duì)類屬性和方法的封裝,很多面向?qū)ο笏枷氲耐昝乐髁x者希望在“視覺”上也達(dá)到封裝,因此就產(chǎn)生了“動(dòng)態(tài)原型法”,請(qǐng)看下面的代碼:

function Car(color, title){
   this.color = color;
   this.title = title;
   if (typeof Car._initialized == "undefined") {
      Car.prototype.start = function(){
          alert("Bang!!!");
      };
      Car.prototype.material = "steel";
      Car._initialized = true;
   }
}

我們看,其實(shí)Car.prototype的屬性定義是可以被放進(jìn)Car function的定義之中的,這樣就達(dá)到了“視覺”封裝。但是我們沒有單純的move,我們需要加一個(gè)條件,讓這些賦值操作只執(zhí)行一次,而不是每次創(chuàng)建對(duì)象實(shí)例的時(shí)候都執(zhí)行,造成內(nèi)存空間的浪費(fèi)。添加_initialized 屬性的目的就在于此。

  

對(duì)于所有用字面量創(chuàng)建的對(duì)象而言,其prototype對(duì)象均為Object.prototype(作為一個(gè)特殊對(duì)象,Object.prototype沒有原型對(duì)象):

var x = {a:18, b:28};

console.log(x.__proto__);//Object {}

  

而對(duì)于所有用new操作符創(chuàng)建的對(duì)象而言,其prototype對(duì)象均為constructor函數(shù)的prototype屬性:



var x = {a:18, b:28}; function Test(c){ this.c = c; } Test.prototype = x; var t = new Test(38); console.log(t);//Object {c=38, a=18, b=28} console.log(t.__proto__);//Object {a=18, b=28} console.log(t.__proto__.__proto__);//Object {}
  

總結(jié)出來一句話就是:用構(gòu)造函數(shù)方式定義對(duì)象的所有非函數(shù)屬性,用原型方式定義對(duì)象的函數(shù)屬性。


整理于:
http://dbear.iteye.com/blog/613745
http://www.cnblogs.com/tomxu/archive/2012/02/21/2352994.html

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85657.html

相關(guān)文章

  • 面向?qū)ο蟮?JavaScript

    摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對(duì)象存在。而在基于原型的面向?qū)ο蠓绞街?,?duì)象則是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對(duì)這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣鳌1疚膶⒒貧w面向?qū)ο蟊疽?,從?duì)語言感悟的角度闡述為什...

    novo 評(píng)論0 收藏0
  • 理解javascript核心知識(shí)點(diǎn)

    摘要:作用域鏈的作用就是做標(biāo)示符解析。事件循環(huán)還有個(gè)明顯的特點(diǎn)單線程。早期都是用作開發(fā),單線程可以比較好當(dāng)規(guī)避同步問題,降低了開發(fā)門檻。單線程需要解決的是效率問題,里的解決思想是異步非阻塞。 0、前言 本人在大學(xué)時(shí)非常癡迷java,認(rèn)為java就是世界上最好的語言,偶爾在項(xiàng)目中會(huì)用到一些javascript,但基本沒放在眼里。較全面的接觸javascript是在實(shí)習(xí)的時(shí)候,通過這次的了解發(fā)現(xiàn)...

    laznrbfe 評(píng)論0 收藏0
  • 講清楚之 javascript原形

    摘要:構(gòu)造函數(shù)和實(shí)例都通過屬性指向了原形。代碼示例是構(gòu)造函數(shù)的實(shí)例的屬性與的屬性保存的值相等,即他們指向同一個(gè)對(duì)象原形。 講清楚之javascript原型 標(biāo)簽: javascript javascript 中原形是一個(gè)比較難于理解的概念。javascript 權(quán)威指南在原形這一章也花了大量的篇幅進(jìn)行介紹,也許你已經(jīng)讀過javascript 權(quán)威指南,或者已經(jīng)是讀第N篇了,然而這篇文章的目...

    高勝山 評(píng)論0 收藏0
  • 深入理解JavaScript原型與繼承

    摘要:深入理解原型與繼承看過不少書籍,不少文章,對(duì)于原型與繼承的說明基本上讓人不明覺厲,特別是對(duì)于習(xí)慣了面向?qū)ο缶幊痰娜藖碚f更難理解,這里我就給大家說說我的理解。 深入理解:JavaScript原型與繼承 看過不少書籍,不少文章,對(duì)于原型與繼承的說明基本上讓人不明覺厲,特別是對(duì)于習(xí)慣了面向?qū)ο缶幊痰娜藖碚f更難理解,這里我就給大家說說我的理解。 首先JavaScript是一門基于原型編程的語言...

    mengbo 評(píng)論0 收藏0
  • JavaScript 工廠函數(shù) vs 構(gòu)造函數(shù)

    摘要:當(dāng)談到語言與其他編程語言相比時(shí),你可能會(huì)聽到一些令人困惑東西,其中之一是工廠函數(shù)和構(gòu)造函數(shù)。好的,讓我們用構(gòu)造函數(shù)做同樣的實(shí)驗(yàn)。當(dāng)我們使用工廠函數(shù)創(chuàng)建對(duì)象時(shí),它的指向,而當(dāng)從構(gòu)造函數(shù)創(chuàng)建對(duì)象時(shí),它指向它的構(gòu)造函數(shù)原型對(duì)象。 showImg(https://segmentfault.com/img/bVbr58T?w=1600&h=900); 當(dāng)談到JavaScript語言與其他編程語言...

    RayKr 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

PiscesYE

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<