摘要:對象字面量創(chuàng)建對象張三學生這種方式的好處顯而易見,就是解決了之前的缺點。構(gòu)造函數(shù)模式張三學生李四學生與之前工廠模式的方法對比變量名首字母大寫了在函數(shù)內(nèi)沒有顯式的創(chuàng)建及返回對象而使用了創(chuàng)建時使用了關(guān)鍵字。
面向?qū)ο笫荍S的重點與難點,但也是走向“掌握JS”的必經(jīng)之路,有很多的文章或書籍中都對其進行了詳細的描述,本沒有必要再寫這些,但是對于學習來說,講給別人聽對自己來說是一種更好的受益方式。我想通過簡潔的語言來描述創(chuàng)建對象的方法以及這種方法的優(yōu)缺點。
本系列內(nèi)容:
基本創(chuàng)建模式
對象字面量創(chuàng)建對象
工廠模式
構(gòu)造函數(shù)模式
更新時間
2015年12月6日:創(chuàng)建
2017年7月8日:精簡內(nèi)容,修正錯誤
一、創(chuàng)建對象創(chuàng)建對象的方法有許多,各有利弊。知其然,做到會用;知其所以然,做到為什么用這種方法。才能是真正的掌握。
1.1 基本創(chuàng)建模式var person = new Object(); person.name = "張三"; person.job = "學生"; person.viewName = function(){ console.log(this.name); }
這是一種最基礎(chǔ)的創(chuàng)建對象的方法,使用新建Object的方法創(chuàng)建對象,并且為其添加屬性和方法。
但這種方式有個不好的地方是重復使用了多個person變量,而且沒有任何的封裝性可言,于是就出現(xiàn)了更受開發(fā)人員喜愛的對象字面量形式。
1.2 對象字面量創(chuàng)建對象var person = { name: "張三", job: "學生", viewName: function(){ console.log(this.name); } }
這種方式的好處顯而易見,就是解決了之前的缺點。
但在實際需求中,需要創(chuàng)建一批類似的對象就有些力不從心了。比如一個小組有六個成員,我要基于每個組員進行對象實例化,那么我要寫6遍以上的代碼,并且為其命名為person1~person6。如果可以像流水線一般創(chuàng)建對象就好了:給其提供原料(名字和職務),讓其自動創(chuàng)建出組員,使用函數(shù)恰好能做到。
1.3 工廠模式var person = function(name, job){ var o = new Object(); o.name = name; o.job = job; o.viewName = function(){ console.log(this.name); } return o; }; var person1 = person("張三","學生"); var person2 = person("李四","學生");
工廠模式利用"創(chuàng)建對象函數(shù)"形成流水線的模式,使其流程化,將創(chuàng)建的過程都封裝到函數(shù)中,對外只暴露每個對象的特性(通過參數(shù)的形式傳入)。
具體的實現(xiàn)流程是:在函數(shù)內(nèi)創(chuàng)建了一個對象,將傳入的參數(shù)作為對象的屬性,在最后將其返回。調(diào)用函數(shù),函數(shù)就會返回擁有特定屬性的對象。
工廠模式流程化了創(chuàng)建對象的方法,使其創(chuàng)建對象變得非常簡便,但其中出了一個問題,既然person1和person2都使用person函數(shù)創(chuàng)建,那么,有什么方法可以證明person1和person2"師出同門"呢?或者用JS的話說是怎樣解決對象識別問題,答案是工廠模式不能證明。于是又出現(xiàn)了構(gòu)造函數(shù)模式,用此模式可以確定person1和person2的關(guān)系。
1.4 構(gòu)造函數(shù)模式var Person = function(name, job){ this.name = name; this.job = job; this.viewName = function(){ console.log(this.name); } } var person1 = new Person("張三","學生"); var person2 = new Person("李四","學生");
與之前工廠模式的方法對比:
Person變量名首字母大寫了
在函數(shù)內(nèi)沒有顯式的創(chuàng)建及返回對象而使用了this
創(chuàng)建時使用了new關(guān)鍵字。
Person變量首字母大寫是為了區(qū)別普通函數(shù),除此之外,別無它用。既然Person的首字母大寫只是為了讓自己一眼辨別出他是構(gòu)造函數(shù),在功能上是相同的。那么寫成person當然可以,只是這樣不推薦(無法區(qū)分普通函數(shù)與構(gòu)造函數(shù))。
使用new操作符必須經(jīng)歷四個步驟
創(chuàng)建一個新的對象
將構(gòu)造函數(shù)的作用域賦值給新對象
執(zhí)行構(gòu)造函數(shù)的代碼:為其添加屬性和方法
返回新的對象
使用new操作符創(chuàng)建的對象都有一個constructor屬性,該屬性指向構(gòu)造函數(shù)。
person1.constructor == Person; // true person1.constructor === person2.constructor;// true console.log(person1.constructor);// 返回構(gòu)造函數(shù) //function (name, job){ // this.name = name; // this.job = job; // this.viewName = function(){ // console.log(this.name); // } //}
在測試的時候發(fā)現(xiàn)一個問題:不使用new關(guān)鍵字創(chuàng)建Object對象為什么constructor有值?
共享方法再回到原來的需求,小組有兩個人,我要創(chuàng)建兩個對象,對象的名字和職位可能不一樣,但是打印每個人的名字這個方法是一樣的。
對于以上幾種模式創(chuàng)建的對象。
person1.viewName === person2.viewName;// false
我每次創(chuàng)建一個對象,都創(chuàng)建一次viewName,但是每次都不相等(person1.viewName == person2.viewName返回false)。且如果有一天我們想把viewName方法改成return返回name值,我要每個對象都改嗎?我們只要把這個方法做成對象公用的就好了,我們可以這樣:
var Person = function(name, job){ this.name = name; this.job = job; this.viewName = viewName; } function viewName(){ console.log(this.name); } var person1 = new Person("張三","學生"); var person2 = new Person("李四","學生");
但是這又出現(xiàn)了一個問題,沒有封裝性可言啊,viewName明明是Person的私有方法,但是放在外面,變成了誰都可以調(diào)用,原型函數(shù)模式解決了這個問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78273.html
摘要:對象重新認識面向?qū)ο竺嫦驅(qū)ο髲脑O計模式上看,對象是計算機抽象現(xiàn)實世界的一種方式。除了字面式聲明方式之外,允許通過構(gòu)造器創(chuàng)建對象。每個構(gòu)造器實際上是一個函數(shù)對象該函數(shù)對象含有一個屬性用于實現(xiàn)基于原型的繼承和共享屬性。 title: JS對象(1)重新認識面向?qū)ο? date: 2016-10-05 tags: JavaScript 0x00 面向?qū)ο?從設計模式上看,對象是...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街校瑢ο髣t是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣鳌1疚膶⒒貧w面向?qū)ο蟊疽猓瑥膶φZ言感悟的角度闡述為什...
摘要:基于原型的面向?qū)ο笤诨谠偷恼Z言中如并不存在這種區(qū)別它只有對象不論是構(gòu)造函數(shù),實例,原型本身都是對象。允許動態(tài)地向單個的對象或者整個對象集中添加或移除屬性。為了解決以上兩個問題,提供了構(gòu)造函數(shù)創(chuàng)建對象的方式。 showImg(https://segmentfault.com/img/remote/1460000013229218); 一. 重新認識面向?qū)ο?1. JavaScript...
閱讀 3511·2023-04-25 14:57
閱讀 2560·2021-11-22 14:56
閱讀 2079·2021-09-29 09:45
閱讀 1761·2021-09-22 15:53
閱讀 3313·2021-08-25 09:41
閱讀 896·2019-08-29 15:22
閱讀 3289·2019-08-29 13:22
閱讀 3122·2019-08-29 13:08