夯實基礎,完全掌握js的核心技術(二):面向對象編程(Object Oriented Programming)

單例設計模式(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. 高級單例模式

  1. 在給命名空間賦值的時候,不是直接賦值一個對象,而是先執行匿名函數,造成一個私有做用域AA(不銷燬的棧內存),在AA中建立以愛國堆內存,把內存地址賦值給命名空間
  2. 這種模式的好處:咱們徹底能夠在AA中創造不少內容(變量或者函數),哪些須要供外面的調取使用的,咱們暴露到返回的對象中(模塊化實現的一種思想)

以下圖例子:設計模式

var nameSpace = (function () {
	var n = 12
	function fn () {}
	return {
	fn: fn
	}
})

this:數組

  1. 給當前元素的某個事件綁定方法,當事件觸發方法執行的時候,方法中的this是當前元素操做的元素對象
  2. 普通函數執行,函數中的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

解析以下圖:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Q0FpCDWm-1594650877968)(https://cdn.nlark.com/yuque/0/2020/png/148146/1594520569024-f2ffeb80-2d05-425c-8ec4-be5785044520.png#align=left&display=inline&height=384&margin=%5Bobject%20Object%5D&name=image.png&originHeight=768&originWidth=1858&size=536805&status=done&style=none&width=929)][外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9kNh0vA6-1594650877970)(https://cdn.nlark.com/yuque/0/2020/png/148146/1594520727798-261bb33a-195d-494d-b546-d23685fde946.png#align=left&display=inline&height=395&margin=%5Bobject%20Object%5D&name=image.png&originHeight=790&originWidth=1604&size=531226&status=done&style=none&width=802)]瀏覽器

5. 基於單例的模塊化開發

  1. 團隊協助開發的時候,會把產品按照功能板塊進行劃分,每一個功能板塊都有專人負責開發
  2. 把各個版塊之間公用的部分進行提取封裝,後期在想實現這些功能,直接的調取便可

工廠模式(Factory Pattern)

工廠模式(Factory Pattern)框架

  1. 把實現相同功能的代碼進行‘封裝’,以此來實現‘批量生產’(後期想要實現這個功能,咱們只需執行函數便可)
  2. ‘低耦合高內聚’:減小頁面中的冗餘代碼,提升代碼的重複使用率
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 對象類 (基類)




模塊化

  1. Number數字類 String Boolean Null Undefined Array RegExp Function Date …函數

  2. HTMLCollection 每個元素集合都是它的實例this

  3. NodeList

  4. EventTarget

    Node: Element:HTMLBodyElement HTMLDivElement<br />       WindowProperties: Window: window對象就是它的實例
  5. 基於基類,咱們能夠建立不少本身的類(自定義類)

結構以下圖:
image.png


構造函數(constructor)

1. 基於構造函數建立自定義類(constructor)

  1. 在普通函數執行的基礎上「new xxx()」,這樣就不是普通函數執行了,而是構造函數執行,當前函數名稱稱之「類名」,接收返回的函數結果是當前類的一個實例
  2. 本身建立的類名,最好第一個單詞首字母大寫
  3. 這種構造函數設計模式執行,主要用於組件、類庫、插件、框架等的封裝,平時編寫業務邏輯通常不用這樣處理
function Fn() {}
var f1 = new Fn()  //Fn是類 f1是類的一個實例
var f2 = new Fn()   // f2也是Fn的一個實例
// f1和f2是獨立的,互不影響

2. JS中建立值有兩種方式:

  1. 字面量方式
var obj = {}
  1. 構造函數模式
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. 構造函數運行機制


普通函數執行:

  1. 造成一個私有的做用域
  2. 行參賦值
  3. 變量提高
  4. 代碼執行
  5. 棧內存釋放問題

普通函數執行流程以下圖:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PeIVDwOX-1594650877973)(https://cdn.nlark.com/yuque/0/2020/png/148146/1594610009317-c06bea64-a992-4168-881b-10915b310d57.png#align=left&display=inline&height=288&margin=%5Bobject%20Object%5D&name=image.png&originHeight=576&originWidth=1918&size=57493&status=done&style=none&width=959)]

構造函數執行:
既有普通函數執行的一面,也有構造函數執行的一面


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是私有做用域的一個私有變量而已
  1. 像普通函數執行同樣,造成一個私有做用域(棧內存)

行參賦值、變量提高,都是私有變量

  1. 【構造函數獨有操做】在js代碼自上而下執行以前,首先在當前造成的私有棧中建立一個對象(建立一個堆內存:暫時不存儲任何東西),而且讓函數中的執行主體(this)指向這個新的堆內存(this === 建立的對象)
  2. 代碼開始自上而下執行
  3. 【構造函數執行獨有】代碼執行完成,把以前建立的堆內存地址返回(瀏覽器默認返回)

image.png
image.png


5. 構造函數中的一些細節問題

  1. 構造函數執行,不寫return ,瀏覽器會默認返回建立的實例,若是本身寫了return
  • return 是一個基本值,返回的結果依然是類的實例
  • 直接return是結束代碼執行,不會覆蓋實例
  • 若是返回的是引用值,則會把默認值返回的實例覆蓋,此時接收到結果就再也不是當前類的實例了

因此構造函數執行的時候,儘可能減小return使用,防止覆蓋實例
**

  1. 在構造函數執行的時候,若是不須要傳遞實參數,咱們能夠省略小括號,仍是建立實例(和加小括號是沒有區別的)
  2. instanceof: 檢測某一個實例是否隸屬於這個類
  3. in:檢測當前對象是否存在某個屬性(無論當前這個屬性是對象的私有屬性仍是公有屬性,只要有結果就是true)
  4. hasOwnProperty: 檢測當前屬性是否爲對象的私有屬性(不只要有這個屬性,並且必須仍是私有的才能夠)

原型鏈設計模式(prototype & proto

1. 原型鏈機制

原型(prototype)、原型鏈(proto
[函數]
普通函數、類(全部的類:內置類、本身建立的類)
[對象]
普通對象、數組、正則、Math
實例是對象類型的(除了基本類型的字面量建立的值)
prototype的值也是對象類型的
函數也是對象類型








  1. 全部的函數數據類型都是天生自帶一個屬性:prototype(原型),這個屬性的值是一個對象,瀏覽器會默認給它開闢一個堆內存
  2. 在瀏覽器給prototype開闢的堆內存中,有一個天生自帶的屬性:constructor,這個屬性存儲的值是當前函數自己
  3. 每個對象都有一個__proto__的屬性,這個屬性指向當前實例所屬類的prototype

image.png
原型鏈:
它是一種基於__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

解析以下圖:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hPw53hoY-1594650877977)(https://cdn.nlark.com/yuque/0/2020/png/148146/1594649468888-b7feb737-e1e0-4397-8fde-084310ca8ae3.png#align=left&display=inline&height=385&margin=%5Bobject%20Object%5D&name=image.png&originHeight=770&originWidth=1944&size=683618&status=done&style=none&width=972)]

總結:

本篇文章主要分享了面向對象的一些知識,若是想了解更多,請掃下面二維碼,關注公衆號
qrcode_for_gh_4d3763fa9780_258 (1).jpg

相關文章
相關標籤/搜索