摘要:都是構造函數模式創建的原生構造函數。使用構造函數創建對象經歷了以下四個過程創建一個新對象構造函數的作用域交給新對象。
??在創建對象的時候,使用對象字面量和 new Object() 構造函數的方式創建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,對于"懶惰"的程序員來講是不可以接受的。即便你能接受這種創建的方式,也無法保證將所有對象歸類這一哲學問題。
??由此,優秀的程序員們利用現有的規則,創造出了一種種優秀的解決方案 -- 這些優秀的解決方案統稱為設計模式。
??在 JavaScript 中,設計模式由初級到高級的區別是他們的副作用的大小。依次可以分為:
工廠模式
構造函數模式
原型模式
others
??同時,使用設計模式也可以優雅的解決 JavaScript 在 ES6之前都是沒有類的尷尬問題。
工廠模式??工廠模式,顧名思義就是創建對象的一個工廠,工廠可以創造一類具有相似結構和功能的對象。這個模式的誕生也基本解決了:
創建多個對象的時候,需要大量重復代碼
先看下在這種設計模式下,應該如何組織我們的代碼:
function createPerson(name, age) { var obj = new Object(); obj.name = name ; obj.age = age; obj.say = function() { console.log(this.name)} return obj; } var p1 = createPerson("ZhangSan", 12); p1.say() //ZhangSan
這種叫工廠模式的設計模式:是指使用統一的方法(函數,因為 Js 沒有類)來描述對象創建的細節
把這個對象封裝起來,每次使用類似的對象都使用這個工廠函數來創建。
它抽象了創建一個對象的過程。
當然,處于初級階段的 工廠模式, 一定有它處于初級階段的道理:
優勢:
工廠函數可以解決創建多個類似功能對象的問題。
缺點:
工廠模式無法解決對象的識別問題: 不知道對象是什么類型的。
使用工廠函數創建的對象,只有開發者是知道它的類型的(通過工廠函數變量名),但是程序仍然認為它是一個普通的對象。
每個對象都是通過工廠造就的全新的對象。
構造函數模式??在 JavaScript 的開發中,經常會聽說和使用的一個詞語叫做構造函數,這里的構造函數就是出自構造函數模式這一種設計模式。在長時間的傳承中,文化或者其他的名詞都會變成一種泛稱,所以人們常說的構造函數,有的時候指的是構造函數模式,有的時候指的是構造函數模式創造的對象中的構造函數方法(實例的 constructor )。
??構造函數是用來創建特定的類型的對象的。比如Js原生提供的Object, Array。都是構造函數模式創建的原生構造函數。
慣例,看下在這種設計模式下,該如何組織代碼:
function Person (name, age) { this.name = name; this.age = age; this.say = function() { console.log(this.age); } } var p1 = new Person("ZhangSan", 12); var p2 = new Person("LiSi", 22); p1.say() // 12 p2.say() // 22
使用構建函數模式和工廠模式創建對象的區別:
沒有明顯的創建對象的過程: (new Object()的過程)
直接將參數賦值給了 this。(因為 沒有創建明顯的對象,就需要用 this 進行賦值)
沒有 return 。
構造函數的首字母大寫,這是代碼風格上的變化(為了和其他的 OOM 語言的代碼風格保持一致)
創建一個由構造函數創建的對象,需要使用 new Person() 進行創建。
使用構造函數創建對象經歷了以下四個過程:
創建一個新對象
構造函數的作用域交給新對象。this指向新對象
執行內部代碼,給新對象增加屬性和方法
返回新對象
由構造函數創建的對象稱為這個構造函數的實例,在實例中會存在一個 constructor 屬性,這個屬性指向創造它的構造函數。(證明自己從哪里來)
p1.constructor == Person; // true p2.constructor == Person; // true
每一個實例都是可以被檢測出來的,檢測對象是否屬于某一個類型,可以使用 instanceof XX。
p1 instanceof Person // true p1 instanceof Object // true
知道了構造函數模式創建實例的過程和方法,下面介紹一些使用構造函數方法中,一些不為人知的秘密(高級知識點):
使用構造函數的時候常規操作是:使用操作符new。但是也可以直接當做一個普通的函數使用。
// Person 在上個 Demo var p3 = Person("Person3", 33); p3; // undefined; p3.say(); // undefined; Person("Person4", 44); window.say(); // 44;
如果把構造函數當做普通函數使用了,就不能構造實例了,即使構造了實例,也都是 undefined。
直接使用 構造函數當做普通函數使用, 屬性和方法會被添加到全局中(window/global)。
當然也可以使用 call把 this 指向其他對象。(不了解 call,可以先忽略。call 是改變 this 指針的方式之一)。
??了解了高級用法之后,細心的孩子已經發現了構造函數方法作為 Level 2的設計模式,一定有哪里不對。其實很簡單,在構造函數創建的過程中,很好的解決了工廠模式創建對象不知道類型的問題(不知道自己從哪里來)。在構想上,實例的屬性和方法應該都是唯一指向的,理想情況是都指向構造函數。但是差強人意的地方出現了:
屬性都很好的指向了 構造函數。 this.name = name
方法又自己偷摸的創建了新的對象(函數也是對象)。這就不符合理想的情況了,因為這個時候:
p1.say === p2.say // false
原理也很清楚啊:this.say = function() {} 就是 this.say = new Function() 啊。
這個時候,一個構造函數的補救措施出現了:
var Person = function(name, age) { this.name = name; this.age = age; this.say = sayFunc; } var sayFunc = function() { console.log(this.age) }
使用額外的函數,將構造函數內的方法指向外部,這樣就保證了實例方式的相同。
俗話說的好,補救措施終究是補救措施:
在構造函數存在大量的方法的時候,外部會存在數量巨多的補救方法。
補救方法在構造函數的外部,毫無封裝性可言。
外部方法也是一個普通的函數,也可以被其他方法或構造函數執行。
外部方法被添加到 全局(window/global)上,性能浪費。如果在 window 上調用,this 就指向了 window。造成 this 指向混亂(誰調用,this 指向誰)
所以,構造函數的方法仍然是一個不完美的方法。但是在開發速度上,構造函數的設計模式還是有很大優勢的。
而且當你需要你的方法在全局被使用的時候,構造函數模式是最適合的,這也是 Object, Array原生構造函數出現的原因。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/53217.html
摘要:都是構造函數模式創建的原生構造函數。使用構造函數創建對象經歷了以下四個過程創建一個新對象構造函數的作用域交給新對象。 ??在創建對象的時候,使用對象字面量和 new Object() 構造函數的方式創建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,...
摘要:目錄導語理解對象和面向對象的程序設計創建對象的方式的繼承機制原型對象原型鏈與原型對象相關的方法小結導語前面的系列文章,基本把的核心知識點的基本語法標準庫等章節講解完本章開始進入核心知識點的高級部分面向對象的程序設計,這一部分的內容將會對對象 目錄 導語 1.理解對象和面向對象的程序設計 2.創建對象的方式 3.JavaScript的繼承機制 3.1 原型對象 3.2 原型鏈 3.3 與...
摘要:其實在之前的工廠模式里面,也存在這個問題,不過工廠模式更徹底,直接完全創建一個新對象,而構造函數模式的話只是方法會被重新創建。 我來重新學習 javascript 的面向對象(part 1) 很多job 的描述都說要求精通 javascript 面向對象編程,但是根據一般的套路,寫精通其實就是熟練,寫熟練其實就是一般,寫一般其實就是懵逼! showImg(https://segment...
摘要:解決了構造函數模式不能共享方法的問題。六寄生構造模式流程創建一個構造函數,在這個函數內部創建一個對象,用返回對象。除了使用操作符并把使用的包裝函數叫做構造函數以外,這個模式與工程模式其實是一模一樣的。 JavaScript面向對象高級——對象創建模式 一、工廠模式 流程: 定義一個函數,函數返回對象。 適用場景: 需要創建多個對象,都是Object類型。 優點:完成了返回一個對象的...
摘要:對象字面量創建對象張三學生這種方式的好處顯而易見,就是解決了之前的缺點。構造函數模式張三學生李四學生與之前工廠模式的方法對比變量名首字母大寫了在函數內沒有顯式的創建及返回對象而使用了創建時使用了關鍵字。 面向對象是JS的重點與難點,但也是走向掌握JS的必經之路,有很多的文章或書籍中都對其進行了詳細的描述,本沒有必要再寫這些,但是對于學習來說,講給別人聽對自己來說是一種更好的受益方式。我...
閱讀 1601·2023-04-26 01:54
閱讀 1630·2021-09-30 09:55
閱讀 2652·2021-09-22 16:05
閱讀 1866·2021-07-25 21:37
閱讀 2628·2019-08-29 18:45
閱讀 1891·2019-08-29 16:44
閱讀 1890·2019-08-29 12:34
閱讀 1352·2019-08-23 14:02