JavaScript 對象及對象的創(chuàng)建

前言

????即使不了解Javascript的設(shè)計原理和繼承機(jī)制這些東西的時候,我們依然能很好的使用Javascript去設(shè)計前端頁面及功能。

????這得力于傳統(tǒng)jquery時的前端開發(fā)我們把大部分的業(yè)務(wù)邏輯封裝在后臺,前端代碼的邏輯性大大降低,我們只需要使用一點點j和ava語法類似的知識就能寫出所需的javascript代碼。

????這時候我們不需要考慮繼承,不需要考慮復(fù)雜的封裝,甚至連this關(guān)鍵字我們都用的極少。但在接觸了react,vue這些前端框架之后就有必要詳細(xì)的了解與學(xué)習(xí)Javascript了,Javascript已經(jīng)變成一個獨(dú)立于后端的完整的前端框架的一個基礎(chǔ)。

對象及對象的創(chuàng)建

????Javascript是一種基于對象(object-based)的語言,你遇到的所有東西幾乎都是對象。但是,它又不是一種真正的面向?qū)ο缶幊蹋∣OP)語言,因為它的語法中沒有"子類"和"父類"的概念,也沒有"類"(class)和"實例"(instance)的區(qū)分。我們舉幾個例子,一下的都是對象。

????這些基礎(chǔ)的數(shù)據(jù)類型也是對象但是不在本章的討論訪問之內(nèi)。

這兩行都是等價的,都生成了一個名為fun1的(函數(shù))對象。


????這是我們比較常見的對象方式,用大括號的方式創(chuàng)建對象,采用鍵值對的方式描述對象屬性。

????這個對象的結(jié)果其實和第三個對象是一樣的都是可以用{}來表述的。

????我們可以很清楚的看出這都是對象,完全沒有類的概念,我們最后一個例子里的Object是類么?不,不是的。接下來就要說明一下對象的創(chuàng)建方式。

順便給大家推薦一個裙,它的前面是 537,中間是631,最后就是 707。想要學(xué)習(xí)前端的小伙伴可以加入我們一起學(xué)習(xí),互相幫助。群里每天晚上都有大神免費(fèi)直播上課,如果不是想學(xué)習(xí)的小伙伴就不要加啦。

????對象的創(chuàng)建方式只有一種,那就是

????所以我們很清楚了,Object是一個構(gòu)造函數(shù)(對象)。

????這么設(shè)計的原因是因為當(dāng)初javascript的設(shè)計者并不打算引入"類"(class)的概念,因為一旦有了"類",Javascript就是一種完整的面向?qū)ο缶幊陶Z言了,這好像有點太正式了,而且增加了初學(xué)者的入門難度。不過他在設(shè)計創(chuàng)建對象的方式上卻借鑒了C++和java的語法,引用了new關(guān)鍵字,但是javascript是沒有類的?那么new后面跟著是什么呢?它發(fā)現(xiàn)java與C++對象的創(chuàng)建都必須執(zhí)行構(gòu)造函數(shù)(constructor),于是乎他就做了簡化的設(shè)計,在Javascript語言中,new命令后面跟的不是類,而是構(gòu)造函數(shù)。

????所以以上四種范例其本質(zhì)上都是javascript通過new 構(gòu)造函數(shù)的方式隱式或顯式幫我們創(chuàng)建的。我們先詳細(xì)的了解一下構(gòu)造函數(shù)的創(chuàng)建方式再細(xì)說范例中是如何隱式創(chuàng)建的對象。

構(gòu)造函數(shù) construct

示例:

????7丨console.log(zs); //[object Object] ?

{[functions]: , __proto__: { },age: 23,name:"zhangsan",sex: "man"}

????可以看到我們根據(jù)man構(gòu)造函數(shù)創(chuàng)建了一個對象zs,對象有name,age和sex 屬性。在這里面我們可以清楚的看到構(gòu)造函數(shù)給對象設(shè)置屬性的方式是this關(guān)鍵字,this關(guān)鍵字動態(tài)指向的是創(chuàng)建的對象(關(guān)于this的其它問題會另起一章介紹),this關(guān)鍵字后跟著的屬性或方法就是該對象的屬性或方法。但是如果構(gòu)造方法有返回值,那生成的對象就是構(gòu)造方法的返回值了,所以大家在寫構(gòu)造方法時要特別注意,示例如下:

????看到zs的值變成了{(lán)info:‘error’},所以寫構(gòu)造函數(shù)的時候最好也不要寫返回值。但是我發(fā)另一很奇怪的情況,示例如下

丨:"zhangsan",sex: "man"}

????我們看到如果返回的是基本類型,整型,字符串類型等的那構(gòu)造函數(shù)還是生效了,這另我十分費(fèi)解。不過只要記住在我們寫構(gòu)造函數(shù)時不去寫返回值也就能規(guī)避這種問題。

????構(gòu)造函數(shù)創(chuàng)建的方式也不是完全完美的,比如看下面的示例中的sex屬性,如果通過man構(gòu)造函數(shù)創(chuàng)建出來的對象sex都固定是“man”,那每個對象都要分配內(nèi)存來存儲sex屬性是不是有些浪費(fèi)呢?或者就是有些屬性要給所有對象共用的呢?比如對象的方法,完全不需要隨著對象變化,該如何處理?

????為了解決這個問題,javascript為構(gòu)造函數(shù)(函數(shù)類型對象)提供了prototype屬性。

prototype屬性

????prototype只能用于函數(shù)對象,如果你給其它非函數(shù)對象增加prototype屬性,執(zhí)行器會報出該對象無prototype屬性錯誤。

????我們先來一個示例來看prototype如何使用

????我們看到構(gòu)造函數(shù)通過prototype屬性增加的屬性或方法是給所有對象共享的。我們把那些需要共享的方法和屬性放在prototype屬性里,那些不需要共享的屬性和方法,就放在構(gòu)造函數(shù)里面。

????而實現(xiàn)過程是這樣的,當(dāng)實例對象一旦創(chuàng)建,將自動引用prototype對象的屬性和方法。也就是說,實例對象的屬性和方法,分成兩種,一種是本地的,另一種是引用的。

順便給大家推薦一個裙,它的前面是 537,中間是631,最后就是 707。想要學(xué)習(xí)前端的小伙伴可以加入我們一起學(xué)習(xí),互相幫助。群里每天晚上都有大神免費(fèi)直播上課,如果不是想學(xué)習(xí)的小伙伴就不要加啦。

????我們再看一個示例

????我們看到只有通過prototype屬性修改sex對象才能更新全部對象的sex屬性,而單單修改某個對象的sex屬性是無法全局修改的,對于這個我不知道是如何實現(xiàn)的,有知道的不吝賜教。

????我們再看一個示例

????這個示例只是prototype下屬性的修改方式改為對整個prototype屬性的對象進(jìn)行設(shè)置。這種方式可以么?可以,而且修改成這樣對上一個示例的輸出完全沒有影響。但是個人還是不推薦這種方式,因為prototype屬性還有一個特別的方法constructor。

constructor

????我們先介紹下constructor屬性

constructor屬性是指向構(gòu)造方法的引用,也就是說如下兩行代碼是等價的。

????看起來好像沒什么用,但是我們知道prototype可以把自己的屬性傳遞給對象的。也就是說我們可以通過constructor來比較兩個對象是不是同一個構(gòu)造器的實例,示例如下:

????所以通過man.prototype={…}的方式設(shè)置共享屬性會破壞constructor屬性。雖然好像破壞了在我們的使用中不會產(chǎn)生任何影響,但我們還是要知道有這個屬性的存在及prototype的作用。

????prototype還有一些其他方法,但是通過man.prototype={…}方式是破壞不了,只是因為所有對象的這些方法都是一致的,比如isPrototypeOf,hasOwnProperty方法,提供幾個示例,就不詳述了。

????isPrototypeOf 示例是不是來自該構(gòu)造函數(shù)

????hasOwnProperty 每個實例對象都有該方法,用來判斷某一個屬性到底是本地屬性,還是繼承自prototype對象的屬性

????我們再看一下最開始我們說的那個問題,所有的對象生成本質(zhì)上都是通過構(gòu)造函數(shù)生成的。查看的方法很簡單,我們知道每個對象都有一個constructor方法,我們只要輸出每個對象的constructor方法就能找到他的構(gòu)造函數(shù)。

其它問題

????我們說了構(gòu)造函數(shù),什么樣才能算是構(gòu)造函數(shù)呢?所有的函數(shù)都可以是構(gòu)造函數(shù),所有的函數(shù)也只有函數(shù)可以擁有有prototype屬性。而函數(shù)也是對象,如上面例子的fun1函數(shù),它也是由Function()構(gòu)造函數(shù)生成的,fun1是函數(shù)對象,你可以把fun1當(dāng)對象用,給他設(shè)置屬性,方法都是完全沒問題的,但是fun1.prototype設(shè)置的屬性也只能給new fun1()生成的對象使用,不能混淆了。

????有說javascript的繼承機(jī)制是依靠prototype屬性(原型鏈{prototype chain}模式)來實現(xiàn)的,但是因為通過prototype設(shè)置“父對象”的屬性和方法,只能變成“繼承”共享的屬性和方法,每個對象自己私有的屬性和方法是無法繼承的,還是有一些不一樣的。而且說是共享只能說是統(tǒng)一賦值,我們通過對象去修改prototype提供的屬性并不會影響其他對象的該屬性。說是繼承但是不太一樣。

????在理解javascript的對象及對象的創(chuàng)建時要牢記兩點,一個是javascript內(nèi)(幾乎)所有的都是對象,并且對象都有構(gòu)造函數(shù)和一些默認(rèn)方法。比如我有時忘記這兩件事,寫一些奇怪的范例時就很懵逼,為什么會出現(xiàn)這個結(jié)果。如我常忘記prototype屬性指向的也是對象,對象也就會有constructor,isPrototypeOf 等這些方法。

作者:spongeboblz??

來源:CSDN????????????????????????????????????????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??面向?qū)ο螅∣bject-Oriented,OO)的語言有一個標(biāo)志,那就是它們都有類的概念,而通過類可以創(chuàng)建任意...
    霜天曉閱讀 2,261評論 0 6
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,514評論 0 21
  • 面向?qū)ο螅∣bject-Oriented,OO)的語言有一個標(biāo)志,那就是它們都有類的慨念,而通過類可以創(chuàng)建任意多個...
    threetowns閱讀 940評論 0 4
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對象屬性創(chuàng)建對象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,536評論 3 12
  • 下午站上體重秤看到數(shù)字的時候簡直要驚跳起來,臥槽又胖了幾斤! 想到健身卡已經(jīng)辦了一個月了,趁春暖花開狗熊撒歡的季節(jié)...
    貓偲閱讀 431評論 6 4

友情鏈接更多精彩內(nèi)容