摘要:對象字面量創建對象張三學生這種方式的好處顯而易見,就是解決了之前的缺點。構造函數模式張三學生李四學生與之前工廠模式的方法對比變量名首字母大寫了在函數內沒有顯式的創建及返回對象而使用了創建時使用了關鍵字。
面向對象是JS的重點與難點,但也是走向“掌握JS”的必經之路,有很多的文章或書籍中都對其進行了詳細的描述,本沒有必要再寫這些,但是對于學習來說,講給別人聽對自己來說是一種更好的受益方式。我想通過簡潔的語言來描述創建對象的方法以及這種方法的優缺點。
本系列內容:
基本創建模式
對象字面量創建對象
工廠模式
構造函數模式
更新時間
2015年12月6日:創建
2017年7月8日:精簡內容,修正錯誤
創建對象的方法有許多,各有利弊。知其然,做到會用;知其所以然,做到為什么用這種方法。才能是真正的掌握。
1.1 基本創建模式var person = new Object(); person.name = "張三"; person.job = "學生"; person.viewName = function(){ console.log(this.name); }
這是一種最基礎的創建對象的方法,使用新建Object的方法創建對象,并且為其添加屬性和方法。
但這種方式有個不好的地方是重復使用了多個person變量,而且沒有任何的封裝性可言,于是就出現了更受開發人員喜愛的對象字面量形式。
1.2 對象字面量創建對象var person = { name: "張三", job: "學生", viewName: function(){ console.log(this.name); } }
這種方式的好處顯而易見,就是解決了之前的缺點。
但在實際需求中,需要創建一批類似的對象就有些力不從心了。比如一個小組有六個成員,我要基于每個組員進行對象實例化,那么我要寫6遍以上的代碼,并且為其命名為person1~person6。如果可以像流水線一般創建對象就好了:給其提供原料(名字和職務),讓其自動創建出組員,使用函數恰好能做到。
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("李四","學生");
工廠模式利用"創建對象函數"形成流水線的模式,使其流程化,將創建的過程都封裝到函數中,對外只暴露每個對象的特性(通過參數的形式傳入)。
具體的實現流程是:在函數內創建了一個對象,將傳入的參數作為對象的屬性,在最后將其返回。調用函數,函數就會返回擁有特定屬性的對象。
工廠模式流程化了創建對象的方法,使其創建對象變得非常簡便,但其中出了一個問題,既然person1和person2都使用person函數創建,那么,有什么方法可以證明person1和person2"師出同門"呢?或者用JS的話說是怎樣解決對象識別問題,答案是工廠模式不能證明。于是又出現了構造函數模式,用此模式可以確定person1和person2的關系。
1.4 構造函數模式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變量名首字母大寫了
在函數內沒有顯式的創建及返回對象而使用了this
創建時使用了new關鍵字。
Person變量首字母大寫是為了區別普通函數,除此之外,別無它用。既然Person的首字母大寫只是為了讓自己一眼辨別出他是構造函數,在功能上是相同的。那么寫成person當然可以,只是這樣不推薦(無法區分普通函數與構造函數)。
使用new操作符必須經歷四個步驟
創建一個新的對象
將構造函數的作用域賦值給新對象
執行構造函數的代碼:為其添加屬性和方法
返回新的對象
使用new操作符創建的對象都有一個constructor屬性,該屬性指向構造函數。
person1.constructor == Person; // true person1.constructor === person2.constructor;// true console.log(person1.constructor);// 返回構造函數 //function (name, job){ // this.name = name; // this.job = job; // this.viewName = function(){ // console.log(this.name); // } //}
在測試的時候發現一個問題:不使用new關鍵字創建Object對象為什么constructor有值?
再回到原來的需求,小組有兩個人,我要創建兩個對象,對象的名字和職位可能不一樣,但是打印每個人的名字這個方法是一樣的。
對于以上幾種模式創建的對象。
person1.viewName === person2.viewName;// false
我每次創建一個對象,都創建一次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("李四","學生");
但是這又出現了一個問題,沒有封裝性可言啊,viewName明明是Person的私有方法,但是放在外面,變成了誰都可以調用,原型函數模式解決了這個問題。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/49684.html
摘要:對象重新認識面向對象面向對象從設計模式上看,對象是計算機抽象現實世界的一種方式。除了字面式聲明方式之外,允許通過構造器創建對象。每個構造器實際上是一個函數對象該函數對象含有一個屬性用于實現基于原型的繼承和共享屬性。 title: JS對象(1)重新認識面向對象 date: 2016-10-05 tags: JavaScript 0x00 面向對象 從設計模式上看,對象是...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創建了一個具體的對象。對象就是數據,對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:是完全的面向對象語言,它們通過類的形式組織函數和變量,使之不能脫離對象存在。而在基于原型的面向對象方式中,對象則是依靠構造器利用原型構造出來的。 JavaScript 函數式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向對象的語言,或者只是部分具備一些面向對象的特征。本文將回歸面向對象本意,從對語言感悟的角度闡述為什...
摘要:基于原型的面向對象在基于原型的語言中如并不存在這種區別它只有對象不論是構造函數,實例,原型本身都是對象。允許動態地向單個的對象或者整個對象集中添加或移除屬性。為了解決以上兩個問題,提供了構造函數創建對象的方式。 showImg(https://segmentfault.com/img/remote/1460000013229218); 一. 重新認識面向對象 1. JavaScript...
閱讀 3267·2021-11-22 14:44
閱讀 1113·2021-11-16 11:53
閱讀 1264·2021-11-12 10:36
閱讀 699·2021-10-14 09:43
閱讀 3685·2019-08-30 15:55
閱讀 3399·2019-08-30 14:14
閱讀 1734·2019-08-26 18:37
閱讀 3410·2019-08-26 12:12