《JavaScript設計模式與開發實踐》讀書筆記 一

一本很是值得推薦的書,看了前幾章以爲收穫還挺大的,因而整理成了筆記。本篇博客主要是一到三章的內容,也是書籍所分的第一部分,基礎知識,後續內容會盡快更新的。javascript

主要內容:動態類型語言、鴨子類型、this、call、apply、閉包、高階函數。java

第一章、面向對象的JavaScript

  1. 動態類型語言和鴨子類型
    • 編程語言按照數據類型大致能夠分爲兩類,靜態類型語言和動態類型語言
      • 靜態類型語言在編譯時就能發現類型不匹配的錯誤,規定了數據類型,編譯器還能夠對程序進行一些優化,提升程序執行的速度,缺點是會增長更多的代碼
      • 動態類型語言的優勢是編寫的代碼數量更少,專一於邏輯表達,缺點是沒法保證變量的類型
    • 鴨子類型:關注對象的類型,而不關注對象的自己
    • 根據鴨子類型的思想,咱們沒必要藉助於超類,就能夠輕鬆的實如今動態類型語言中實現的一個原則:‘面向接口編程,而不是面向實現編程’
  2. 多態
    • 含義:同一操做做用於不一樣的對象上面,能夠產生不一樣的結果
    • 多態背後的思想是將‘作什麼’和‘說去作以及怎樣作’分離開來,也就是將不變的事物和可能改變的事物分離開來
    • JavaScript對象的多態性是與生俱來的
    • 面向對象設計的優勢是將行爲分佈在各個對象中,並讓這些獨享負責本身的行爲
  3. 封裝
    • 封裝的目的是將信息隱藏
    • 封裝數據只能模擬出public private兩種封裝性,函數建立做用域,let,經過symbol建立私有屬性
    • 封裝的實現:封裝使得對象內部的變化對其餘對象而言是透明的,也就是不可見的,對象對本身的行爲負責。其餘對象或者用戶都不關心它的內部實現,使得對象之間的耦合變鬆散
    • 封裝是靜態語言中一種重要的封裝方式,通常把對象真正類型隱藏在抽象類和接口以後,相比對象類型,客戶更關心對象的行爲,促使工廠方法模式,組合模式的產生,javaScript中沒有對抽象類和接口進行支持,沒有能力進行封裝。
  4. 原型模式和基於原型繼承的JavaScript對象系統
    • 使用克隆的原型模式
    • 克隆是建立對象的手段
    • 原型編程範型的規則
      • 全部數據都要是對象
      • 要獲得一個對象不是經過實例化類,而是找到一個對象做爲原型克隆他
      • 對象會記住它的原型
      • 若是對象沒法響應某個請求,他會把這個請求委託給本身的原型
    • JavaScript的原型繼承
      1. 全部數據都是對象:除了undefined,一切都應是對象。javascript引入兩套類型機制,基本類型和對象類型,number,boolean,string數據類型能夠經過包裝類的方式變成對象數據類型
        • javaScript的根對象是Object.prototype對象,Object.type對象是一個空對象,javascript建立每一個對象,實際都是從它克隆來的
      2. 要獲得一個對象,不是經過實例化,而是找到一個對象做爲原型並克隆它
        • javaScript中沒有類的概念,javaScript函數能夠做爲普通函數被調用也能夠做爲構造器被調用,用new運算符來調用時,此時的函數是構造器
        • new運算符建立對象的過程是先克隆Object.prototype對象,再進行其餘額外操做(爲了性能,並非每次都新克隆對象),過程:先克隆一個對象,取得外部傳入的構造器,將對象指向正確的原型,借用外部傳入的構造器給obj設置屬性,確保是對象並將對象返回
      3. 對象會記住它的原型
        • 仔細的說是記住對象的構造器的原型,把請求委託給構造器的原型
        • __proto__指向該對象的構造器的原型
      4. 若是對象沒法響應某個請求,他會把這個請求委託給它的構造器的原型
      //實現一個類繼承自另外一個類的效果 var A=function(){} A.prototype={name:'sven'} Var B=function(){} B.prototype=new A() var B=new B() console.log(B.name) 
      1. 原型繼承的將來編程

        設計模式是對語言不足的補充,Object.create()是原型模式的自然實現,使用它完成原型繼承更能體現原型繼承的精髓,可是Object.create()建立對象的效率並不高,比構造函數要慢,經過設置構造器的prototype來實現原型繼承的時候,除了跟對象外,任何對象都會有一個原型,而經過Object.create(null)能夠建立出沒有原型的對象設計模式

  5. 原型模式是一個設計模式,也是一種編程範型,構成了javaScript語言的根本,原型模式十分重要,經過原型模式來實現面向對象系統簡單而強大

第二章、this,call,apply

  1. this數組

    • this的指向:
      • 做爲對象的方法調用
      • 做爲普通函數調用
      • 構造器調用
      • Function.prototype.call或Function.prototype.apply調用
    1. 做爲對象的方法調用:this指向該對象
      var obj={ a;1, getA:function(){ alert(this===obj) //true alert(this.a) //1 } } obj.getA(); 
    2. 做爲普通函數調用:this不做爲對象的屬性被調用時,普通函數方式時,此時this總指向全局對象,window
    window.name='globalName' var myObj={ name:'even', getName:function(){ return this.name } } var getName=myObj.getName; console.log(getName()) //globalName 
    1. 構造器調用:javaScript中沒有類,可是能夠從函數構造器中建立對象,也提供了new,使構造函數更像一個類,構造函數和普通函數的區別就是調用方式,用new運算符調用函數時,該函數總會返回一個對象,構造器裏的this就指向返回的這個函數,除非構造器顯示地返回了一個object類型的對象

    4.Function.prototype.call或Function.prototype,apply調用瀏覽器

    丟失的this安全

  2. call和apply閉包

    1. 區別:做用如出一轍,區別僅在於傳入參數形式不一樣,第一個函數指定了函數體this對象的指向,第二個參數爲一個帶下標的集合,能夠是數組,也能夠是類數組,javaScript參數在內部就是一個數組來表示,apply比call的使用率更高,call是包裝在apply上面的一層語法糖
    2. 用途:
      1. 改變this指向
      2. Function.prototype.bind
      3. 借用其餘對象的方

第三章、閉包和高階函數

JavaScript是一門面向對象的編程語言,可是這門語言同時也擁有許多函數式語言的特性 函數式語言的鼻祖是LISP,JavaScript之初參考了Scheme 許多設計模式都是用閉包和高階函數實現的

1.閉包

  1. 變量的做用域:變量的做用域指變量的有效範圍,聲明變量,若是變量前面沒有帶var,就是全局變量
var a=1; var fun1=function(){ var b=2; var fun2=function(){ var c=3; alert(b); //2 alert(a); //1 }; fun2(); alert(c); // c is undefined } func1(); 
  1. 變量的生存週期app

    • 對於全局變量,生存週期是永久的,除非主動銷燬這個變量,對於由var 聲明的局部變量,會隨着函數調用的結束而被銷燬。】
    var func=function(){ var a=1; return function(){ a++; alert(a); } } var f=func(); f() //2 f() //3 // 由於執行`var f= func()`時,f返回了一個匿名函數的引用,它能夠訪問到func()被調用時產生的環境,局部變量a一直處於這個環境,因此局部變量a不會被銷燬。產生了一個閉包結構 
  2. 閉包的更多做用編程語言

    • 封裝變量
      • 閉包能夠幫助把一些不須要暴露在全局的變量封裝成"私有變量",避免這個變量在其餘地方被修改形成錯誤
      • 提煉函數是代碼重構的技巧,經常把可以獨立出來的代碼封裝在獨立的小函數裏,若是小函數不須要複用,最好用閉包將其封閉起來
    • 延續局部變量的壽命
    var report=(function(){ var imgs=[]; return function(src){ var img=new Image(); imgs.push(img); img.src=src; } })(); //解決請求丟失的問題 
  3. 閉包和麪向對象設計

    • 過程與數據的結合是形容面向對象中的「對象」常用的表達
    • 對象以方法的形式包含了過程,閉包是在過程當中以環境的形式包含了數據,一般用面向對象能夠實現的功能,閉包也能夠實現
  4. 用閉包實現命令模式

    • 命令模式的意圖是把請求封裝爲對象,從而分離請求的發起者和請求的接收者。
    // 
  5. 閉包與內存管理

    • 閉包是一個很是大的特性,但有不少誤解
    • 閉包容易形成循環引用,若是此時做用域鏈中保存着DOM節點,就有可能形成內存泄露,這並非閉包和瀏覽器的問題,也不是JavaScript的問題,因爲BOM和DOM中的對象是使用C++以COM實現,COM對象的垃圾回收機制採用的是引用計數,若是兩個對象之間造成了循環引用,那麼兩個對象就都不能被回收,本質上不是閉包形成的。
    • 解決:把循環引用中的變量設爲null,設置爲null表示切斷與它此前引用的值的聯繫

2.高階函數

高階函數:函數能夠做爲參數被傳遞,函數能夠做爲返回值輸出

  1. 函數做爲參數傳遞
    • 回調函數
    • Array.prototype.sort
  2. 函數做爲返回值輸出
    • 判斷數據的類型
    • getSingle
  3. 高階函數實現AOP(面向切面編程)
    • 面向切面編程的主要做用是把一些跟核心業務無關的功能抽離出來,例如日誌統計,安全控制,異常處理等,抽離出來後經過動態織入的方式摻入業務邏輯中,好處是能夠保持業務邏輯模塊的純淨和高內聚性,其次是能夠很方便的複用日誌統計等模塊兒
  4. 高階函數的其餘應用
    • currying
    • uncurrying
    • 函數節流
    • 分時函數
    • 惰性加載函數

 

注:本篇博客主要內容來自書籍原文

相關文章
相關標籤/搜索