單例設計模式(Singleton Pattern)
1. 單例模式解決的問題:
表現形式:javascript
Var obj = { xxx; xxx, … }
2. 做用:
把描述同一件事物的屬性和特徵進行「分組、分類」(存儲在同一個推內存空間中),所以避免了全局變量之間的衝突和污染
var pattern1 = {name: ‘xxx’} var pattern2 = { name: ‘xxx’} //name值並非一個值,屬於兩個堆內存空間中
在單例設計模型中,obj不只僅是對象名,它被稱爲」命名空間[NameSpace]」,
把描述事務的屬性存放到命名空間中,多個命名空間是獨立分開的,互不衝突
java
3. 單例設計模式命名的由來
每個命名空間都是js中Object這個內置基類的實例,而實例之間是相互對立不干擾的,因此咱們稱它爲「單例」:單獨的實例
編程
4. 高級單例模式
- 在給命名空間賦值的時候,不是直接賦值一個對象,而是先執行匿名函數,造成一個私有做用域AA(不銷燬的棧內存),在AA中建立以愛國堆內存,把內存地址賦值給命名空間
- 這種模式的好處:咱們徹底能夠在AA中創造不少內容(變量或者函數),哪些須要供外面的調取使用的,咱們暴露到返回的對象中(模塊化實現的一種思想)
以下圖例子:設計模式
var nameSpace = (function () { var n = 12 function fn () {} return { fn: fn } })
this:數組
- 給當前元素的某個事件綁定方法,當事件觸發方法執行的時候,方法中的this是當前元素操做的元素對象
- 普通函數執行,函數中的this取決於執行的主體,誰執行的,this就是誰(執行主體:方法執行,看方法名前面是否有「點」,有的話,點前面是誰this就是誰,沒有this是window)
function fn () { console.log(1) } var obj = {fn:fn} // 執行的是相同的方法,可是this指向不一樣 obj.fn(); // this=> obj fn(); // this指向window // 自執行函數,方法的this指向window ~function() { // this => window } ()
var n = 2; var obj = { n: 3, fn:(function (n) { n *= 2; this.n += 2; var n = 5; return function(m) { this.n *= 2; console.log(m + (++n)) } //自執行函數執行的時候,堆內存尚未存儲完成鍵值對,和obj尚未關係,此時obj=undefined,obj.n會報錯 })(n) } var fn = obj.fn fn(3) // 9 obj.fn(3) // 10 console.log(n, obj.n) // 8 6
解析以下圖:瀏覽器
5. 基於單例的模塊化開發
工廠模式(Factory Pattern)
工廠模式(Factory Pattern)框架
- 把實現相同功能的代碼進行‘封裝’,以此來實現‘批量生產’(後期想要實現這個功能,咱們只需執行函數便可)
- ‘低耦合高內聚’:減小頁面中的冗餘代碼,提升代碼的重複使用率
function createPerson (name, age) { var obj = {} obj.name = name; obj.age = age; return obj } var p1 = createPerson('xxx', 25) var p2 = createPerson('xxx', 25) console.log()
擁抱面向對象
面向對象編程,咱們須要掌握「對象、類、實例」的概念
對象:萬物皆對象
類: 對象的具體細分(按照功能特色進行分類:大類、小類)
實例:類中具體的一個事物(拿出類別中的具體一個實例進行研究,那麼當前類別下的其餘實例也具有這些特色和特徵)
js中內置類
object 對象類 (基類)
模塊化
-
Number數字類 String Boolean Null Undefined Array RegExp Function Date …函數
-
HTMLCollection 每個元素集合都是它的實例this
-
NodeList
-
EventTarget
Node: Element:HTMLBodyElement HTMLDivElement<br /> WindowProperties: Window: window對象就是它的實例
-
基於基類,咱們能夠建立不少本身的類(自定義類)
構造函數(constructor)
1. 基於構造函數建立自定義類(constructor)
- 在普通函數執行的基礎上「new xxx()」,這樣就不是普通函數執行了,而是構造函數執行,當前函數名稱稱之「類名」,接收返回的函數結果是當前類的一個實例
- 本身建立的類名,最好第一個單詞首字母大寫
- 這種構造函數設計模式執行,主要用於組件、類庫、插件、框架等的封裝,平時編寫業務邏輯通常不用這樣處理
function Fn() {} var f1 = new Fn() //Fn是類 f1是類的一個實例 var f2 = new Fn() // f2也是Fn的一個實例 // f1和f2是獨立的,互不影響
2. JS中建立值有兩種方式:
- 字面量方式
var obj = {}
- 構造函數模式
var obj = new Object()
無論哪種方式創造出來的都是Object類的實例,而實例之間是獨立分開的,因此var xxx = {} 這種模式也是js中的單例模式.
3. 基本數據類型基於兩種不一樣的模式建立出來的值是不同的
- 基於字面量方式建立出來的值是基本類型值
- 基於構造函數建立出來的值是引用類型
var num1 = 12; // 數字類Number實例,數字類的特殊表達方式之一 var num2 = new Number(12); // 數字類的實例 console.log(typeof num1) // "number" console.log(typeof num2) // "object"
4. 構造函數運行機制
普通函數執行:
- 造成一個私有的做用域
- 行參賦值
- 變量提高
- 代碼執行
- 棧內存釋放問題
普通函數執行流程以下圖:
構造函數執行:
既有普通函數執行的一面,也有構造函數執行的一面
function Fn(name, age) { var n = 10; this.name = name; this.age = age + n; } var f1 = new Fn('xxx', 20); var f2 = new Fn('aaa', 30) console.log(f1=== f2); // false:兩個不一樣的實例(兩個不一樣的堆內存地址) console.log(f1.age) //30 console.log(f2.name) // 'aaa' console.log('name' in f1) // true name和age在兩個不一樣的實例都有存儲,可是都是每一個實例本身的私有屬性 console.log(f1.n) // undefined 只有this.xxx =xxx 的才和實例有關係,n是私有做用域的一個私有變量而已
- 像普通函數執行同樣,造成一個私有做用域(棧內存)
行參賦值、變量提高,都是私有變量
- 【構造函數獨有操做】在js代碼自上而下執行以前,首先在當前造成的私有棧中建立一個對象(建立一個堆內存:暫時不存儲任何東西),而且讓函數中的執行主體(this)指向這個新的堆內存(this === 建立的對象)
- 代碼開始自上而下執行
- 【構造函數執行獨有】代碼執行完成,把以前建立的堆內存地址返回(瀏覽器默認返回)
5. 構造函數中的一些細節問題
- 構造函數執行,不寫return ,瀏覽器會默認返回建立的實例,若是本身寫了return
- return 是一個基本值,返回的結果依然是類的實例
- 直接return是結束代碼執行,不會覆蓋實例
- 若是返回的是引用值,則會把默認值返回的實例覆蓋,此時接收到結果就再也不是當前類的實例了
因此構造函數執行的時候,儘可能減小return使用,防止覆蓋實例
**
- 在構造函數執行的時候,若是不須要傳遞實參數,咱們能夠省略小括號,仍是建立實例(和加小括號是沒有區別的)
- instanceof: 檢測某一個實例是否隸屬於這個類
- in:檢測當前對象是否存在某個屬性(無論當前這個屬性是對象的私有屬性仍是公有屬性,只要有結果就是true)
- hasOwnProperty: 檢測當前屬性是否爲對象的私有屬性(不只要有這個屬性,並且必須仍是私有的才能夠)
原型鏈設計模式(prototype & proto)
1. 原型鏈機制
原型(prototype)、原型鏈(proto)
[函數]
普通函數、類(全部的類:內置類、本身建立的類)
[對象]
普通對象、數組、正則、Math
實例是對象類型的(除了基本類型的字面量建立的值)
prototype的值也是對象類型的
函數也是對象類型
…
- 全部的函數數據類型都是天生自帶一個屬性:prototype(原型),這個屬性的值是一個對象,瀏覽器會默認給它開闢一個堆內存
- 在瀏覽器給prototype開闢的堆內存中,有一個天生自帶的屬性:constructor,這個屬性存儲的值是當前函數自己
- 每個對象都有一個__proto__的屬性,這個屬性指向當前實例所屬類的prototype
原型鏈:
它是一種基於__proto__向上查找的機制。當咱們操做實例的某個屬性或者方法的時候,首先找本身空間中私有屬性或者方法
- 找到了,則結束查找,使用本身私有的便可
- 沒有找到,則基於__proto__找所屬類的prototype,若是沒找到,基於原型上的__proto__繼續,向上查找,一直找到Object.prototype的原型爲止,若是再沒有,操做的屬性或者方法不存在
function Fn() { var n = 10; this.AA = function () { console.log('AA') } this.BB = function () { console.log('BB') } } Fn.prototype.AA = function () { console.log('AA[公]') }; var f1 = new Fn; var f2 = new Fn
解析以下圖:
總結:
本篇文章主要分享了面向對象的一些知識,若是想了解更多,請掃下面二維碼,關注公衆號